What is a Microservices architecture?
Microservices architecture became mainstream 5 years ago, and most technology businesses wanted to explore the possibilities of this approach. With a microservices architecture, an application is built as independent components that run each application process as a service. These services communicate via a well-defined interface using lightweight APIs. Services are built for business capabilities and each service performs a single function.
See the graph:
Advantages of Microservices Architecture
Language. Every function of the application runs on its own as an independent service. Because they are independent, the team responsible for one service may choose the language and framework themselves, depending on their needs. It gives those teams flexibility in choosing the programming languages that fit best the issue to solve and the team’s skillset.
Ease of configuration. Traditional architecture creates large monolithic packages whose configuration can be hard to manage. Therefore, deployment takes place seldom, once every few weeks or months. Microservices are small and isolated, so they are packaged and deployed independently of each other. That makes configuration easier to manage so we can deploy often. This way, the deployment becomes a routine operation that can be performed multiple times a day.
Ability to iterate / DevOps pipeline. The system components are independent, and they communicate over APIs, so the team responsible for one functionality can commit code that goes to the DevOps pipeline. Therefore, development teams could iterate as fast as they need to and bring value to the customers.
Smaller impact in case of failure. When one microservice experiences an issue, this will not necessarily impact other microservices, which in most cases continue to work as normal. As a result, a well-designed microservices architecture can improve the robustness of the application.
Independent scaling. If the number of users increases driving load on the system, some services might need additional help. The system should be able to add capacity automatically to a particular service until the load subsides. Eventually, when the load goes back to its regular cadence, those additional services can scale back to normal.
Cloud adoption. While microservices can certainly be run on-premise, horizontal scaling is much easier to do in the cloud. If your application experiences peak hours and you run it on-premise, your infrastructure needs to be able to support those peaks, and a lot of it will sit idle at non-peak hours.
What business challenges does a microservices architecture solve?
- Scaling your monolith architecture is an issue. When your system has 20 users, the capacity of your current server is enough to support their operations. When the number of users doubles, you are going to need 2,5-3 times the server capacity, incurring serious financial investments. The trick is you will not be using this whole capacity all the time because your customers do not need to use all the functions of your system in proportional amounts. That is why it is better to put those specific functions in separate containers and grow the server capacity on an as-needed basis.
Therefore, you might want to think about going to microservices when you anticipate significant growth in the number of users and you realize that with monolith architecture your new users will cost you more than you can potentially earn from them.
2. Your monolith architecture starts to fail. Some monolith architectures have been functioning for some time now because their owners have naturally chosen an extensive way of development. This means that they would be building more and more functionality upon their monolith. While this approach works fine for some, it generally causes problems with the system’s tolerance to failures. When a monolith fails, all of its functions become unavailable, even if the failure is caused by a non-critical function. When those instances occur more and more often, this may put your whole business in jeopardy, with users switching to more progressive and functional products.
What are the steps for migrating to Microservices?
Analyze your system
Before you start refactoring anything, make sure you understand how your application works. Most large enterprise applications that have been in the market for quite some time, were born as monoliths. As time passes, it gets harder to keep up with the whole system architecture and describe how it is organized from the technology standpoint.
Before you start migrating, you need to stabilize the code and clear the architecture. To ensure that refactoring is taking place to enhance your code and make it simpler, you need to have rigorous testing, which is the foundation of refactoring. Without well-defined test cases that verify your code behavior’s correctness, you cannot be sure that you have not altered the code’s external action.
Make it observable
Companies will benefit from microservices architecture if they determine the best way to implement monitoring to support their business needs. Developers should identify the right monitoring support strategy to track all system calls and service interactions in case of failure without creating performance problems. It is vital to be able to react quickly when your monitoring indicates a problem. In particular, any incident management must involve operations and the development team, both in fixing the immediate problem and the root-cause analysis to ensure the underlying problems are fixed.
Make it easy to deploy
With many services to manage, you need to be able to deploy them quickly. This usually includes two factors: technical setup and new organizational approaches. The technical solution such as deployment pipelines needed to automate the process, decreasing and finally eliminating the need for manual intervention. While the DevOps culture is required to ensure that, provisioning and deployment can be done rapidly.
Decompose application into small services
As the first step, singling out a small non-critical function that is fairly decoupled from the monolith, does not require changes to many client-facing applications that are currently using the monolith and possibly does not need a data store. Such an approach will give the opportunity to validate delivery strategies, upskill the team members, and build out the minimum infrastructure needed to deliver independently deployable secure services that expose self-serve APIs.
Proceed with decomposing the application piece after piece until you reach your business objective. In most cases, enterprises partially keep their monolithic structure in the core, and microservices cover the rest of the environment. The cost of ownership of monolithic core will not have a linear dependence on the number of users anymore.
What are some pitfalls you may stumble on during the migration process?
- Coupling services incorrectly. The main idea of microservices is to single out independent services that do not rely on each other in their operations. Each of the services can be modified without shutting down the other parts of the application. However, an easy mistake to make is to keep services tightly coupled as they were in the monolithic design. This mistake is common because monolithic applications are very much dependent on strong connections between their associated components.
- Incorrect choice of the technology stack. Each business has its own sets of issues and constraints, and it should choose its technology stack accordingly. If you choose a technology that no one later wants to work with, you lose options for developing and expanding your app as a result, which will negatively affect your business. When you cannot upgrade your app and add new features to it, you may lose clients and miss your business goals. In the case when a technology founder decides not to support this technology anymore, it means that apps built with it will end up having major security problems.
- Managing separate teams working on microservices. Successful migration towards microservices architecture depends on the proper organization structure more than any other factor. This architecture enforces an organizational structure of autonomous teams, each responsible for one or multiple services. Allowing developers to work independently and choose a technology stack on their own creates a sense of ownership of a particular part of the ecosystem. This builds extra language barriers, leading to additional difficulties and blaming when attempting to connect the pieces together.
- Not well-understood domain. Microservices only work for problems that scale well horizontally. And even if it is the case, microservices come with considerable operational complexity. If you need to develop an MVP quickly, with a single small team, it makes much more sense to create a monolith that has all the required functionality, evolve it, and then move to a microservice architecture when you are hitting team or application scaling challenges.
Microservices may be more complex than traditional architecture, and they require stronger collaboration during development. Not every applicant may be suited to microservices, so you have to consider the pros and cons when making a decision to migrate.
Migration to microservices is the process initiated by the business management to address serious issues with system stability and scalability. This decision should be justified economically when expenses for running a monolith become too high. It is best to start small, separating non-critical functions first. Building new system functions on microservices is also a good idea.
You should also keep in mind that new technologies imply new knowledge in your company, meaning that you would need new policies and a monitoring system in place. Microservices is an expensive technology, so it will work for architectures that are mature enough.