In our first post of this series, we looked at how microservices help you build applications with an eye towards the future. And in our second post, we took a deep dive into how microservices work. But what if you currently have a monolithic application? How do you know if it’s time to move to microservices? And if so, how do you get there?
As we mentioned before, knowing why to build a microservice is only half the battle. Knowing when (or when not) to build one can be a trickier question. There’s no one size fits all. That said, there are a few questions you can ask to help decide if you’re ready for microservices. We’ll explore them in this final post of our series.
Reading the Signs
Is your organization or team experiencing exceptional growth in both employee base and technical stack?
As a codebase grows to a certain size, more people are needed to maintain it. But anyone who has worked on a single codebase with ten other engineers knows the struggle of dealing with merge conflicts during code reviews. If a team is losing valuable time trying to resolve conflicts, it might be time for microservices. Microservices help distribute development teams more efficiently, as complex backend systems can be built faster by dividing workloads into multiple small teams, with each team responsible for a given set of microservices.
Is your application down often?
Every time you deploy an application, it breaks. Or the backend system is seemingly down all the time for maintenance. If these scenarios sound all too familiar, it might be time to shift from a monolithic architecture to microservices.
Are you having difficulty scaling hardware to optimize application performance?
Larger and more complex applications require additional hardware to perform well. Some parts of an application might put more demand on the hardware than others, and the whole application can face degraded performance due to a single poorly-performing feature. Microservices allow individual units of business logic to be assigned their own dedicated hardware, and they can be scaled independently of other services. A slower-performing process can be isolated and capped to a fixed about of CPU, memory, disk, and network bandwidth, which means it can’t steal resources from other features.
Choosing the Moment
Once you’ve decided to build a microservice, the next questions are when to build it and when to switch over. That’s a hard question to answer for any organization. The monolith architecture works for small applications and small engineering teams. But when does the monolith stop working?
It turns out growth is often the death of the monolith. Organizations in the process of undergoing exceptional growth, in both the employee base and in technology stack, can achieve that growth by switching to microservices. If the engineering team is losing valuable time resolving merge conflicts, then it might be time for microservices. If the growing backend system is down all the time for maintenance, then microservices might be the answer. The answer of when to build a microservice is when growth is expected.
Hardware provides a great example of this, as it can only be scaled horizontally so much. Maybe those high-CPU and high-memory servers are too expensive and too underutilized during non-peak hours. The cloud is becoming more appealing with the ability to provision hardware as needed, and smaller servers with lightweight workloads become easier to bring up and tear down in response to changing demands. Microservices have lower hardware requirements, and they can start up quickly to meet peak demands.
Making the Move
Monoliths present a number of challenges that you’ll need to tackle in the move to microservices. A monolith has a tendency toward tight coupling of components, as well as stateful behavior. The application was never intended to live as separate and isolated components working in concert to make a system. The monolith may also be rooted to the infrastructure it lives on, depending on system resources such as a local filesystem and network. What’s more, you need to keep everything up and running during the transition. So how do you move to microservices? Let’s break it down.
Step 1: Determine Your Domains
Your first task is to look at all the features of the application and organize them into logical business units, or domains. For example, your application may have major features related to login/logout, user data, and session management. These features can be logically organized into a single business domain called Authentication. Repeat this step for all of the other domains in your application.
Step 2: Prepare the Monolith
Next, get your application ready for the big break up. To do this, decouple components within the application along the lines of the business domains you came up with. This will result in a number of edge and middle modules within the application, each dedicated to a particular domain, like our Authentication example. You’ll also need to move stateful in-memory stores into shared datastores. Finally, put a router in front of the monolith to smooth the rollout of microservices.
Step 3: Work From the Bottom Up
As you begin breaking out microservices from the monolith, it’s always best to start at the bottom and work your way up. First, create a separate database to store data for the domains you are moving to microservices. Next, break out the data access modules that access this data into middle microservices. Finally, break out edge modules that consume this data into edge microservices. When everything’s ready to go, use the router to toggle redirection to the new edge services. Keep repeating this same process for each domain until all of your modules are broken out and the monolith is no more.
In the diagram below, the Login, Users, and Sessions modules were decomposed into modules within the monolith, and then broken out as separate microservices.
One challenge you’ll encounter during the transition is the need to support both the microservices and the monolith side by side. That also means duplicating work, as you’ll often have to make changes or fixes in both places. The good news is that organizing your monolith similarly to your microservices makes it easier to copy-and-paste code between them.
If your application and organization are both set for growth, microservices can help you meet the challenge of building modular, scalable, highly-available solutions. When you’re ready, you need to organize your application’s features into domain-specific modules, then break them out one by one.
Just remember that transitioning from a monolith won’t happen in a single overnight deployment. You need to strategize as you cherry-pick domains out of the monolith. The key is to complete the transition to microservices and not leave your application in limbo. If you’d like to learn more about how to make the move to microservices, or if you need some help, feel free to ask us. That’s what we’re here for.