When too many people are working on a single tightly coupled codebase, as is normal in monolithic applications, bottlenecks are a usual challenge together with reliability and scaling problems. This is why, a Statistics survey says that 85% of respondents of large organization have migrated to a loosely coupled microservices architecture. While this could be interpreted as bigger organizations are the ones gaining benefits from microservices, this is far from the truth. Smaller companies can also benefit from a microservices architecture and in fact many already do so. If you are not sure whether your business is a good candidate for migrating to microservices, then this article provides a checklist.
If your organization is planning to start migrating partially or wholly from monolith to microservices then this article is for you. Here is an insight on what iTech advices our customers when it comes to a successful migration.
Incrementally extract modules out of the monolith – Strangler Pattern
Microservices-based apps uses business logic to divide the components into a single purpose, stand-alone units. To enable such independence, each microservice is developed as a separate software container that has its own code and database.
When refactoring from monolith to microservices, one of the recommended ways is to start implementing any new functionality as separate services right away. However, since the existing monolithic architecture still supports the majority of the existing functionality, the only way to eliminate the monolith entirely is to start incrementally refactoring modules one by one into the new microservices architecture. This is the Strangler Pattern of transition – transform, co-exist, eliminate. This is the recommended method to refactor code in a large web application by replacing incrementally each functionality with a new web service.
Here is an example that will more easily explain the concept of incremental migration. In a courier company, the order and delivery management were part of a single system. This made it difficult to improve on the algorithms of the delivery system ( to meet new market demands) without affecting the order management system since both were intertwined in the monolith application. The result was a loss in efficiency as well as customer satisfaction. The decision was made to separate the delivery management system but in incremental stages that would not affect the existing business workflows. This was how it was done:
Step 1: Split the code of order management and delivery management and keep it as loosely coupled modules in the same monolithic system.
Step 2: Split the database into two with a separate database schema for each. Data from the monolithic database are segregated into their respective databases. Triggers are also defined that replicates the data into each new database.
Step 3: Define a separate service for each of these workflows. The two new microservices still remain in test phase and will not go into production yet. Even when functionality is extracted into the new service, it is important that if unexpected errors arise in production, in the initial stages, that a switch back to the old monolith service can be done without affecting existing business.
Step 4: Eliminate or decommission the old monolith. Once any glitches in the new system have been identified and resolved , it is time to fully direct production traffic into the new stand alone microservices driven functionality. At this point the monolithic system is switched off.
Modelling based on the reality of a business – Domain-driven design (DDD)
Domain-driven design or as it is more commonly referred to DDD, is the approach usually selected to build services from a system with a complex business domain. Most large organizations fall in this category. DDD is usually used to build software that solves real-world business problems. A domain in this context is a sphere of knowledge within the business a company runs.
While microservices architecture is known for the benefits brought through its independent deployability, it is not easy to migrate legacy systems to this architecture. The migration approach has to deal with a complex and intertwined existing system and trying to create independent modules without affecting the rest of the monolithic system. This is why domain-driven design is recommended because it helps to define service boundaries.
When iTech begins work with organizations wanting to migrate to microservices, this is our first step in the process – a DDD modeling on the existing client’s monolithic application. This is crucial because while a monolith might appears like one solid box, internally there are different units of work defined from a business-domain perspective. While the code is usually not organized around this perspective, these business-domain boundaries (called bounded contexts) become the unit of decomposition when creating separate microservices.
By setting these bounded contexts, we can understand which team will own the model, how it will be used within the application as well as the code bases and database schema that will be required. When the models are restricted within such business-domain boundaries then only a single bounded context is the priority for each model and there is no distraction from any other code that might have leaked through from other functionalities.
Domain-driven design can best be explained with a sales and support example. In sales and customer support applications, the bounded contexts can be easily identified. Have a look at the image below for the context for the sales and customer support modules. Bounded contexts can have unrelated concepts, for instance a customer complaint ticket that exists only in the customer support module. However, there can also be shared contexts between the two – like products and customers that are common both in sales and support.
Migrating software systems from monolith to microservices is a complicated process. However, when done the right way, the projected timelines for completion will not combust midway through the project. Each application has its own unique architecture and that means that the migration strategy should also be tailored specifically for each business.
DevOps must be a critical part of the migration process. This is because it speeds up the process by making the dev team and the operations team to work closely towards a specific goal. The DevOps pipeline is geared to getting the development team to understand fully the production environment in which the new app will run. The benefits of a DevOps pipeline is that it results in improved code and product quality, as well as ensures that new updates can be released at a faster frequency.
If you are considering re engineering your existing platform but don’t know how to begin, talk to our team of experts for insights tailored to your business needs.