The original link
Microservices architecture has become the de facto standard for modern application development. The microservices architecture does solve some problems, but it’s not a silver bullet. It also has its own disadvantages, some problems need to be solved. This needs to be addressed by learning general patterns and using reusable solutions. This is why we discuss design patterns for microservices. Before delving into design patterns, it is important to understand what the microservices architecture is based on:
- scalability
- availability
- The elastic
- Independence, autonomy
- Decentralized management
- Fault isolation
- self-sufficiency
- Continuous delivery through DevOps
Applying all of these principles brings some problems and challenges. Let’s discuss these problems and their solutions.
1. Break down patterns
A. Service function decomposition
The problem
Microservices are loosely coupled by applying the single responsibility principle. However, breaking an application into pieces must be logical. How do you break down your application into smaller services?
The solution
One strategy is to decompose by business function. A business function is how a business creates value. The functional set of a business depends on the business type. For example, an insurance company’s business includes sales, marketing, insurance, claims processing, bookkeeping, auditing and so on. Each business function can be considered a service, but business-oriented rather than technology-oriented.
B. Decompose by subdomain
The problem
Breaking down by business function is a good start, but you might run into god classes that don’t break down easily. These classes appear in multiple services. For example, the Order class is used for Order management, Order fetching, Order shipping, and so on. How do I break this down?
The solution
For the “God class”, domain-driven Design (DDD) comes galloping to the rescue. It uses the concept of subdomain and bounded context to solve this problem. DDD breaks up the whole domain model into subdomains. Each subdomain has a model whose scope is called a bounded context. Each microservice is developed around a bounded context.
Note: Finding subdomains is not an easy task and requires an understanding of the business logic. Like business functions, subdomains need to be identified by analyzing business and organizational structures and analyzing different areas of expertise.
C. Strangler Pattern
The problem
So far, all we’re talking about is breaking down undeveloped applications. However, 80 percent of our work is refactoring developed applications, which are big, integrated applications. Applying the above design patterns can be very difficult, and breaking them down while they are still in use can be a daunting task.
Which brings me to a joke:
A famous heart surgeon had his motorcycle engine broken and was sent to the garage to have it repaired. The repairman deftly took the engine apart, repaired it and put it back on. He said to the doctor: “The engine is the heart of the motorcycle, we both repair the heart, but why is the income gap so big?” The doctor thought for a while and said to the repairman, “Try not to turn off the engine while you are repairing the car.”
The solution
Use the Strangler mode. The Strangler pattern is like a vine winding around to kill a tree. This works well in Web applications, where the service can be split into multiple domains and deployed as a separate service for each URI request. This is done one field at a time. This results in two separate applications on the same URI space. Eventually, the new app strangles the old app, and eventually you can “kill” the integrated app.
2. Integration mode
A. API Gateway mode
The problem
When an application is broken down into smaller services, there are several issues that need to be addressed:
- How to invoke multiple microservice producers.
- On different channels (desktop, phone, and tablet) the same background needs to respond to different data because the UI may be different.
- Different consumers may require different data formats. Who will do the data conversion?
- How to handle different protocols, some of which may not be supported by microservice producers?
The solution
API gateways help to solve many of the problems caused by microservice implementations, not just those mentioned above.
- An API gateway is a single entry point to any microservice invocation.
- Can act as a proxy service to direct requests to the correct microservice. Abstract the provider details.
- Radiate a request to multiple services and aggregate the results back to the consumer.
- Generic apis do not address all consumer needs, and this solution can provide fine-grained apis for each client type.
- Protocol conversions can be made, such as AMQP to HTTP.
- You can take the responsibility of authentication/authorization off microservices.
B. Aggregation mode
The problem
In the API Gateway pattern, we have discussed the issue of aggregated data. We’ll talk about it in full here. After breaking down the business functions into small chunks of logical code, it is necessary to think about how the data returned by each service can work together. This task cannot be left to the consumer, who may then need to understand the internal implementation of the producer.
The solution
The aggregation pattern is about how data from different services is aggregated and returned to the consumer. This can be done in two ways:
- A composite microservice invokes all required microservices, merges and transforms data.
- The API gateway can also split requests into multiple microservices and aggregate data.
The recommended course of action is to choose the first option if there is application business logic, and the second option if not.
C. Client UI combination mode
The problem
When services are decomposed into business functions and subdomains, users have to fetch data from multiple microservices. In an integrated world, all data is usually retrieved with a single request, and then the UI can be refreshed or submitted. That’s no longer the case, and we need to know how to do it.
The solution
With microservices, design the UI like a skeleton, with multiple page nodes. Each node will request the corresponding microservice to obtain data. This is really called a composite UI for services. Frameworks like AngularJS and ReactJS can easily implement this pattern. This is called a single page application (SPA), which allows an application to refresh an area of the page rather than the entire page.
Microservices Design Patterns (PART 2)