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):

{
   "order_id": 123,
   "customer_info": { "id": 456, "name": "John Doe" },
   "payment_info": { "method": "Credit Card", "amount": 100.0 },
   "shipping_info": { "address": "123 Main St", "status": "processing" },
   "order_created_timestamp": "2024-12-17T10:00:00Z"
}        

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

{
  "order_id": 123,
  "customer_id": 456,
  "status": "processing"
}        

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:

class OrderACL:
    def init(self, monolith_order_service):
        self.monolith_order_service = monolith_order_service

    def get_order_for_microservice(self, order_id):
        # Step 1: Fetch order from monolith
        legacy_order = self.monolith_order_service.get_order_by_id(order_id)

 
        # Step 2: Translate legacy order to microservice order
        microservice_order = {
            "order_id": legacy_order["order_id"],
            "customer_id": legacy_order["customer"]["id"],
            "status": legacy_order["shipping"]["status"]
        }
        return microservice_order        

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:

{
   "order_id": 123,
   "customer_info": { "id": 456, "name": "John Doe" },
   "payment_info": { "method": "Credit Card", "amount": 100.0 },
   "shipping_info": { "address": "123 Main St", "status": "processing", 
   "order_created_timestamp": "2024-12-17T10:00:00Z"
}        

5: Event Published (Monolith to Microservice)

  • The monolith publishes an event (e.g., OrderCreated) 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 OrderCreated 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).

{
  "order_id": 123,
  "customer_id": 456,
  "status": "processing"
}        

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.

import requests
def send_transformed_data_to_microservice(transformed_data):
    url = "https://order-service/api/orders"
    headers = {'Content-Type': 'application/json'}
    response = requests.post(url, json=transformed_data, headers=headers)
    return response        

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.

@app.route('/api/orders', methods=['POST'])
def create_order():
    order_data = request.json
    # Process the order (e.g., save to DB, update status, etc.)
    return jsonify({"message": "Order created successfully"}), 201        

10: Microservice Sends Event (Optional)

  • If needed, the Order Microservice may emit its own event (e.g., OrderProcessed) 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

2 个月

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

回复
Vijay Vishnu

Transforming Experienced Tech Professionals (7-15 YOE) into Cloud & AI Experts | Scalable Systems Specialist |Tech Stack Simplifier

2 个月

Amit Kumar I liked ACL layer. Thanks

Jayas Balakrishnan

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

2 个月

Awesome details - thanks for sharing.

Gajendra Kumar Yadav

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

2 个月

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 ????

要查看或添加评论,请登录

Amit Kumar的更多文章

  • ?? Deploying Microservices in AWS EKS using Ingress resource

    ?? Deploying Microservices in AWS EKS using Ingress resource

    In my previous article, I demonstrated how to deploy separate Load Balancer services for each microservice in AWS EKS…

    1 条评论
  • Microservices deployment in EKS

    Microservices deployment in EKS

    ?? Deploying Orders & Products Microservices in AWS EKS: Let’s do a hands-on deployment of Orders & Products…

    10 条评论
  • What is Disaster in terms of cloud computing?

    What is Disaster in terms of cloud computing?

    A disaster refers to any unexpected event or situation that disrupts the normal operations of cloud-based systems…

    4 条评论
  • AWS Well-Architected Framework

    AWS Well-Architected Framework

    AWS Well-Architected Framework Overview The AWS Well-Architected Framework is a set of best practices designed to help…

    2 条评论
  • ALL ABOUT AWS LAMBDA SERVICE

    ALL ABOUT AWS LAMBDA SERVICE

    AWS Lambda Overview AWS Lambda is a serverless compute service provided by Amazon Web Services (AWS). It allows to run…

    7 条评论
  • Taco Bell's Event-Driven Architecture with AWS Serverless Services

    Taco Bell's Event-Driven Architecture with AWS Serverless Services

    Taco Bell serves over 42 million customers weekly across 7,000+ restaurants. To streamline and optimize their order…

    3 条评论
  • AWS Elastic Container Service (ECS)

    AWS Elastic Container Service (ECS)

    Overview of ECS AWS Elastic Container Service (ECS) is a scalable container management service that allows you to…

  • Building a Secure and Scalable API Architecture for Enterprise Applications

    Building a Secure and Scalable API Architecture for Enterprise Applications

    In this article, I am trying to explain a secure, scalable, and resilient API architecture which I implemented for my…

    2 条评论
  • Common Amazon API Gateway Patterns for microservice architecture:

    Common Amazon API Gateway Patterns for microservice architecture:

    API Gateway: API Gateway is a fully managed service that allows to create RESTful and WebSocket APIs at any scale. API…

  • EC2 Cost Optimization

    EC2 Cost Optimization

    Let’s focus on smart savings, not just cutting costs indiscriminately. Remember, not all savings are truly beneficial.

    6 条评论

社区洞察

其他会员也浏览了