Dev Learning Lab

The labs on this site need JavaScript to run. The same content is written out below.

Learn › Architecture and operations › Splitting into services

Gateway and gradual migration

Breaking up a huge server piece by piece without stopping it

You put a gateway in front of an existing server (a monolith) that holds every feature in one lump, and hand requests over to new services one route at a time. The address that users see does not change.

Checked against documentation and standards · The path and weight predicates of Spring Cloud Gateway

Concepts in this lab

API gateway
The single entry point that receives all client requests first and forwards them to the right internal service. It handles common functions such as authentication, rate limiting, and logging in one place. Clients do not need to know the layout and addresses of the internal services.
Strangler fig pattern
A way to replace an existing system gradually by moving features to a new system one at a time, instead of replacing it all at once. At the front, where requests arrive, only the requests for features that have been moved go to the new system, and the existing system keeps handling the rest. When all features have been moved, the existing system is removed.
Monolithic architecture and microservice architecture
A monolithic architecture builds all features as one application and deploys them together. A microservice architecture splits the features into small services, and each one is developed, deployed, and scaled independently. With microservices, each service can be deployed and scaled separately and failures are isolated, but the complexity of communication between services, data consistency, and operations grows a lot.
Reverse proxy
A server that receives client requests on behalf of internal servers, forwards them to those servers, and returns their responses to the client. The client does not know the actual servers directly. Its roles include distributing requests across several servers, handling TLS, caching, and protecting the internal servers.
Rolling, blue-green, and canary deployments
Ways to deploy a new version without interrupting the service. A rolling deployment replaces servers with the new version a few at a time, in turn. A blue-green deployment prepares a complete, separate environment for the new version and then switches the traffic all at once. A canary deployment applies the new version to only some users first, checks that there are no problems, and then expands it gradually.

Try these

Running with the default settings

  1. All of the user's requests come in through one place, the gateway. After doing the common work (token validation, logging, rate limiting), the gateway looks at the path and decides which server behind it to pass the request to. The user does not know how many servers are behind it.
  2. GET /orders/1: The path starts with /orders. This path is configured to be passed to the new service. → Order service (new)
  3. POST /payments: The path starts with /payments. It is not a path with its own rule, so it goes to the existing server. → Existing server (monolith)
  4. GET /members/me: The path starts with /members. It is not a path with its own rule, so it goes to the existing server. → Existing server (monolith)
  5. POST /orders: The path starts with /orders. This path is configured to be passed to the new service. → Order service (new)
  6. GET /orders/2: The path starts with /orders. This path is configured to be passed to the new service. → Order service (new)
  7. GET /members/7: The path starts with /members. It is not a path with its own rule, so it goes to the existing server. → Existing server (monolith)
  8. POST /orders: The path starts with /orders. This path is configured to be passed to the new service. → Order service (new)
  9. GET /payments/9: The path starts with /payments. It is not a path with its own rule, so it goes to the existing server. → Existing server (monolith)
  10. GET /orders/3: The path starts with /orders. This path is configured to be passed to the new service. → Order service (new)
  11. GET /orders/4: The path starts with /orders. This path is configured to be passed to the new service. → Order service (new)

Result of this run

Code

# Spring Cloud Gateway
spring.cloud.gateway:
  routes:
        - id: order
          uri: http://order-service
          predicates:
            - Path=/orders/**
        - id: legacy                   # everything else goes to the existing server
          uri: http://legacy-monolith
          predicates:
            - Path=/**

# Common filters: token validation, request logging, rate limiting

Assumptions of this model

This is a fixed example of 10 requests. The ratio setting is assigned in a simple way so that the difference shows within the 10 requests (for 50%, order requests alternate; for 10%, only the fifth order request goes to the new service). The configuration example follows the path and weight predicates of Spring Cloud Gateway. Separating the data and synchronizing the two systems, which are the hardest parts of moving a feature, are not covered.

Previous lab: Saga and outbox · Next lab: CI/CD pipelines

Concepts in this lab

What this lab shows

Settings

Code


      
    

Diagram

Run comparison

Try these