Monolith to microservice

Monolith to microservice

Let’s discuss the difference between monolith and microservice first,

1.     Architecture:

  • In Monolith arch, application is a single unified unit where all components (UI, business logic and data layer) are tightly coupled/integrated into one codebase and deployed as a single unit.

  • In Microservice arch, application is split into independent, loosely coupled services. Each service represents a specific business function for e.g. user service, order processing service, payment service etc. It can be developed & deployed independently.

2.     Scaling:

  • In Monolith arch, whole application must be scaled since all components are tightly coupled regardless of demand and which may result in inefficiencies and become costly to maintain.

  • In Microservice arch, each service can be scaled independently based on its specific needs.

3.     Development & maintenance:

  • In monolith, since it’s a single codebase it simplifies the development initially but become complex as application grows.

  • In microservice, it allows to work on different services independently however managing multiple services can increase operational overhead and complexity.

4.     Fault isolation:

  • In monolith, failure in one part of application can potentially bring down the entire system since all components are closely interconnected.

  • In microservice, if one service fails, it doesn’t affect other services which improves the system resiliency.

5.     Technology:

  • In monolith, generally uses a single technology stack since all parts are tightly coupled.

  • In microservice, each service can use different technologies, framework, or programming lang based on its requirement.

6.     Data:

  • In monolith, usually apps rely on a single database for all needs which simplify data management but may create bottlenecks.

  • In microservice, usually each service manages its own data and can have a different database store as well. It supports better data isolation but requires more complex data management strategies such as distributed transactions.


How to migrate/convert monolith to microservices?

The Strangler Fig Pattern is an approach used to gradually refactor or migrate a monolithic application to a microservices architecture without completely disrupting the existing system. Here's how you can apply the Strangler Fig Pattern step-by-step for a migration:

Credit: AWS

1. Understand the Monolith

  • Document the current architecture, including how the modules interact and depend on each other.

  • Identify domains or functional areas that can be decoupled from the monolith and are suitable for migration into a microservice.

2. Set Up a Gateway/Proxy

  • Implement a proxy layer (e.g., API Gateway, Reverse Proxy) between the monolith and the client. This allows you to route requests to either the monolith or new microservices as you migrate.

  • The proxy acts as a routing layer that can send traffic to the new microservices once they are deployed while still maintaining traffic to the old monolith.

3. Incremental Migration by Feature

  • Identify a small, self-contained feature or service within the monolith that can be extracted and converted into a microservice.

  • Create the new microservice for that feature, implementing it independently, and ensure it handles the required business logic.

4. Add an Anti-Corruption Layer (ACL)

  • It ensures that the new services don’t inherit the complexities, poor design choices, or outdated paradigms of the old system and ACL acts as a translation layer that isolates your microservices from the monolith's legacy code and models.

  • It translates data and concepts between the monolith and the microservices, ensuring that the new services use their own domain model rather than being constrained by the old system's models.

5. Implement Communication Between Monolith and Microservices

  • Start by decoupling the monolith from the specific feature by adding an API to the microservice. The monolith should be modified to call the new service for its specific part, instead of doing everything internally.

  • Use synchronous (REST) or asynchronous (event-driven with messaging queues) communication depending on your architecture and need.

6. Route Traffic

  • Gradually update the proxy layer to route traffic for specific features to the new microservice instead of the monolith.

  • Ensure that the routing is done based on feature or functionality, so that the client doesn't need to be aware of the migration.

7. Ensure Data Consistency

  • Initially, both the monolith and microservices may need to share the same database. This can be tricky, so you can: Use Database per Service strategy later to separate databases for each microservice. Handle data synchronization and consistency with event-driven patterns or CQRS (Command Query Responsibility Segregation).

8. Complete Migration

  • Once all the core functionality has been migrated, fully decouple the monolith, and shift all relevant traffic to the microservices.

At this point, the monolith becomes redundant, and you can decommission it.


How can I prevent new microservice to inherit the complexities, poor design choices and outdated paradigm of old system:

By using an Anti-corruption layer:

The Anti-Corruption Layer (ACL) is essentially a middleware layer or program that sits between the monolithic system and the new microservices, translating data, adapting interfaces, and ensuring that the new system is decoupled from the old system. Its main purpose is to prevent the "corruption" of the new microservices by legacy monolithic code, data models, or business logic. It acts like a translator or adapter to convert data and interactions between incompatible systems.

Example of ACL as a "Stage" to Translate Data:

1. Monolith Order Data (e.g., the legacy system might return a complex object):

2. Microservice Order Data (the microservice may only care about a simplified order structure):

3. ACL as a Translator: The ACL will translate the legacy data format from the monolith into the simplified format that the microservice expects. It might look like this in code:


Let's see a complete picture in step-by-step process:

1: Call Made to Monolith

  • A client or user makes a request to the system (e.g., an order creation).

  • The request is routed through the Proxy Layer.

2: Proxy Layer Routes the Request

  • The Proxy Layer checks if the requested feature is part of the monolith or a new microservice.

  • If the feature is still in the monolith, the request is forwarded to the monolith.

3: Monolith Processes the Request

  • The monolith handles the business logic (e.g., creating an order) and generates a payload with all required details (e.g., customer, payment, shipping).

4: Payload Generated by Monolith

  • The monolith generates the payload in its legacy format:

5: Event Published (Monolith to Microservice)

  • The monolith publishes an event (e.g., ) to an event broker (e.g., Kafka, RabbitMQ, SQS).

  • Event is sent asynchronously to notify the system that a new order has been created.

6: ACL Listens for the Event

  • The Anti-Corruption Layer (ACL) listens to the event from the monolith.

7: ACL Transforms Legacy Data

  • The ACL processes the event and transforms the legacy data (e.g., converts the monolith's payload into a simplified version suitable for the microservice).

8: Transformed Data Delivered to Microservice (Multiple way to do it: direct API call, Asynchronous, Event Driven)

  • The transformed data is sent to the Order Microservice for processing.

  • The ACL makes an HTTP request (e.g., a REST API call) to the Order Microservice's endpoint, passing the transformed data in the request body.

9: Order Microservice Saves the Data

  • The Order Microservice processes the data (e.g., updates its own database with the new order).

  • The Order Microservice may update the order status, associate it with other microservices (e.g., payment, inventory), and perform its own business logic.

10: Microservice Sends Event (Optional)

  • If needed, the Order Microservice may emit its own event (e.g., ) to notify other microservices (e.g., payment, shipping).

11: Proxy Layer Routes Future Requests

  • Once the Order Microservice is fully migrated, the Proxy Layer continues to route requests to the Order Microservice rather than the monolith.

12: Full Transition

  • As more features are migrated to microservices, the monolith is gradually decommissioned.

  • All requests for order-related functionality are now routed to the Order Microservice, and the monolith no longer handles any new functionality.

This process shows the gradual migration, ensuring that features can be moved to microservices incrementally while the legacy monolith remains functional during the transition.


Conclusion:

Converting from a monolith to microservices is a gradual process which offers significant advantages, especially in terms of scalability, flexibility and fault isolation but introduces complexity in communication, data management, and operations. A well-planned, incremental approach minimizes risks and ensures business continuity during the migration.

 

Sarathlal Saseendran

Senior Enterprise Solutions Architect at Voyon Group

7mo

If a FOOL does Microservice this will be a BIG FAILURE. Monolithic always has better options.

Like
Reply
Vijay Vishnu

Distributed Systems + Real-time Data Engineering + AI | Building 29 AI-Enhanced Production Systems | Mission: 1B+ TPS

7mo

Amit Kumar I liked ACL layer. Thanks

Srikanth Reddipalli

Cloud & IT Infrastructure Lead | FinOps | AIOps

7mo

Thank you for sharing such a detailed explanation of the Strangler Fig Pattern and its role in transitioning from monolithic to microservices architecture. The step-by-step breakdown, especially the role of the Anti-Corruption Layer, provides great insights into managing complexities during migration.

Jayas Balakrishnan

Hands-On Technical Leader @Federal Reserve Bank NY | 8x AWS, KCNA, KCSA & 3x GCP Certified | Multi-Cloud Architect | US Citizen

7mo

Awesome details - thanks for sharing.

Gajendra Kumar Yadav

Solution Architect - AWS Cloud and Java - Certified Full Stack Developer

7mo

Love the ACL, we used it very early somewhere in 2020-2021. Very helpful bridge between monolith and MS, otherwise seen people are building another monolith in Microservices too. Nice article, covering all aspects 👏👏

To view or add a comment, sign in

Others also viewed

Explore topics