1. Introduction
The Romance of The Three Kingdoms begins with a sermon: “As the general trend of the world, long divided, long united, long divided….” . In fact, most things that experience have such a law, in software system design, will also experience such an iterative evolution. In more than two years in a service architecture design and practice, the author has experienced from the huge application system architecture split into many different micro service application, then the application of the micro service of different restructuring into has the ability to reuse of China, but the objective is to better support the business development, improve software development efficiency and quality. This article mainly wants to sort out some basic knowledge of microservice architecture, so that everyone has a comprehensive and systematic understanding of microservice architecture.
2. Single architecture vs. microservice architecture
2.1 Definition of software architecture
Software architecture is a set of structures needed to build an application system, including software elements, the relationships between elements, and the attributes of both. How to decompose software elements and the relationships between them becomes very important. A good software architecture has two characteristics:
- Rational allocation of production relations and productivity, so that people with different professional knowledge and technical stacks are involved in the development of software systems, efficient collaboration;
- Allows each software element to have a clear definition and responsibility, and a good, efficient interaction mechanism.
2.2 Single Application Architecture
Application development uses a single architecture, where all the code is managed in a code repository and finally packaged into a deployment package that runs on a single process. There are two types of typical three-tier application architecture and hexagonal application architecture.
In the early stages of a project, a single architecture does provide an unparalleled efficiency boost to development, with the following benefits:
- Application development is simple, basically all the code is managed in a warehouse;
- Very convenient for large-scale changes;
- Easy to test, just write a few end-to-end tests;
- Deployment is straightforward and scale-out is easy.
However, with the expansion of the business, the number of business modules and the amount of code will increase sharply. At this time, the disadvantages of single architecture gradually become obvious:
- With the increasing complexity, the coupling degree between modules is higher and higher, and the maintenance cost is very high;
- The update iteration cycle is longer, and the time from code submission to actual deployment is longer, and sometimes not delivered;
- It is difficult to scale and evolve iteratively, and it is always impossible to upgrade using outdated technology stacks or components.
2.3 Microservice Architecture
Before talking about microservices architecture, it is important to mention the classic extension cube theory. The extension cube defines three different ways to extend applications:
- The X-axis extension implements load balancing of requests across multiple identical instances;
- Y-axis extensions split applications into services based on functionality;
- The Z-axis extension routes requests based on their attributes.
Microservices architecture can be understood as an extension of “modular design”, except that these “functional modules” run as separate deployment packages in their own processes. Each service is independent of each other and has its own private database, and can only communicate with each other via API.
The evolution from a single architecture to a microservice architecture also brings the following benefits:
- From the point of view of code management, each service is small, mostly due to more than a dozen interfaces or service methods, very easy to maintain;
- From the perspective of operation and maintenance management, each service can be deployed independently and is easy to scale.
- From the perspective of team management, the scope of responsibilities can be better divided;
- From the perspective of software development in general, software systems can be delivered and deployed sustainably.
Similarly, microservices architecture has the following drawbacks:
- It is difficult to split and define services;
- It increases the complexity of the system, making the development, testing and deployment more difficult.
- The development team needs to be coordinated when deploying the capabilities of multiple services.
3. Definition and composition of microservices architecture
In a microservices architecture, it is important to consider that the decision model consists of multiple patterns. In terms of levels, it can be roughly divided into three layers: application-related, application-based, and infrastructure-related.
- Apply related patterns: service splitting, database architecture, maintaining data consistency issues, testing related;
- Apply infrastructure-related patterns: boundary issues, security, transactional messaging, communication style, reliability, monitoring;
- Infrastructure-related modes: deployment of applications and services, and service discovery.
3.1 Service Splitting
It is difficult to decompose a single application system into a series of services. There are two strategies for decomposition:
- Decompose according to business capability
- Decomposition by subdomain
3.2 Communication Mode
Applications using microservices architecture are distributed systems, and interprocess communication is an important part. There are several communication modes:
- Communication style: which interprocess communication mechanism to use;
- Service discovery: how a client obtains the real IP address of a specific instance;
- Reliability: how to ensure reliable communication between services if they are not available;
- Transactional messaging: how to integrate database transactions to send messages, publish events, and update business data;
- External API: How the application client communicates with the service.
3.3 Data Consistency Mode
In the microservice architecture, each service has its own independent database. The transaction mechanism of 2PC in the original single-application architecture is no longer applicable in the microservice architecture, and middleware similar to distributed transaction is needed to ensure the consistency of data.
3.4 Observability
In the microservice architecture, a request will often go through the jump of multiple service instances, and the application performance problems such as high latency are difficult to observe and solve. The following patterns are needed to design a set of monitored services:
- Health check API: Every microservice application needs an API that returns health;
- Log aggregation: All logs of server nodes are written to a centralized Log server. Log search can be performed on this server and alarms can be generated based on Log conditions. The typical solution is Log path + container +ES.
- Distributed link tracing: assign a unique ID to each external request for tracing external requests across services, newlic/ Skywalking;
- Application metrics: Metrics used for maintenance, such as call counts;
- Audit logs: record user behaviors.
3.5 Deployment Modes
While deploying a single application is a straightforward operation, deploying a microservices-based application is much more complex, typically consisting of dozens or even hundreds of services. Traditional application deployment based on manual replication to the server is no longer suitable for microservices architecture and requires a highly automated deployment infrastructure, such as a deployment platform that can manage requirements tasks, code changes, and server resource environments all in one.
3.6 Security-Related
In microservice architecture, the authentication of user identity and permission is usually done by the gateway. The common solution is the access token mode of Outh2 protocol. The gateway passes the access token to the service, authenticates the token and obtains the information about the user.
3.7 Tests
The method and emphasis of testing individual architecture are different from those of microservice architecture. Microservice architecture makes testing easier due to the smaller granularity of services. The emphasis is on testing whether different services work together, while using complex, slow and fragile end-to-end testing to test multiple services. The following modes can simplify the testing workload and improve the efficiency of testing by using separate testing services:
- Consumer-driven testing: Verifying that the service meets the expected functionality of the client;
- Consumer contract test: Verify that the client of the service can communicate with the service properly;
- Service component testing: Tests services in an isolated environment.
3.8 Related patterns for infrastructure and border issues
In micro service architecture, each service must implement many functions associated with infrastructure, such as observability and service discovery, externalized configuration mode, etc., need to develop a micro service architecture infrastructure base, so when developing new micro service business can quickly access and development on base.
4. Service splitting
At that time, the whole background system also encountered the problem of “monomer hell”, so we decided to split it into a series of microservices in each domain to alleviate a series of problems in development/deployment. We mainly followed the following split strategy and guiding principles.
4.1 Split Policy
All starting points are business. First, functional requirements or user stories should be sorted out to define the system operations, and then the system operations should be transformed into a complete request. Based on the request, the specific responsibilities and boundaries of services can be initially defined, and then the interface and collaboration between services can be defined.
There are two types of service separation: one is the aggregation of capability boundaries and responsibilities from business capabilities to services, and the other is the division of services according to the subdomains in the DDD domain design.
4.4 Guidelines for Splitting
- Single responsibility (SRP): Originally meant that each class carries only one responsibility. In microservices architecture, it means that each microservice should be as small as possible, cohesive, and independently supporting a closed loop of business.
- Closure principle (CPP) : is defined as all the classes in the package should be a collection of similar changes, if a change to the pack, you need to update the class should be in the package, in micro service architecture, refers to when demand change, need to change the scope of service component is controllable is a best service, best can be done in a development team.
4.5 Difficulty in Splitting Single Application Services
- Network delay: after the request passes through the layers of service forwarding, the communication link will increase by N times, of course, the communication will be delayed;
- Inter-process communication leads to reduced availability, which increases the traffic of the network where the microservice cluster resides. Even in the LAN, availability will be reduced due to network jitter or link hotspot.
- Maintaining data consistency between services and obtaining a consistent view of data makes it difficult to implement transactions between different database instances.
5. Interprocess communication
5.1 Communication Mode
- One-to-one: Each client request is handled by one service instance;
- One-to-many: Each client request is processed by multiple service instances;
- Synchronous mode: client requests require real-time response from the server. The client may block while waiting for the response.
- Asynchronous mode: client requests do not block the process and server responses can be non-real-time;
5.2 Communication based on synchronous remote Procedure call mode
Working principle of remote procedure call (RPC), business logic in the client calls the proxy interface, this interface by the agent of a remote procedure call adapter class implements, call the agent will send a request to the service, the request by the remote procedure call server adapter classes, the class through the interface to invoke the service business logic, and then reply will be sent back to the procedure call agent, The agent returns the result to the client’s business logic.
The hystrix component can be used to handle these problems and ensure high availability of the service. However, based on the circuit breaker mode, it is “know later and realize later”. There are two discovery modes to realize service discovery: application service and platform service.
- Client discovery mode: Service instances use the service registry to group their network locations. Clients obtain the list of available service instances from the registry and perform load balancing among them.
- Platform-level service discovery patterns: Many deployment bottles, such as Docker and Kubernetes, have built-in service registries and service discovery mechanisms. The deployment platform provides a DNS name, virtual IP address, and DNS name for each service. When a customer requests a DNS name and virtual IP address, the deployment platform automatically routes it to one of the available service instances.
5.3 Asynchronous Message-based communication
With the messaging mechanism, communication between services is accomplished by exchanging messages asynchronously. The industry logic in the sender calls the sending interface, which encapsulates the underlying communication mechanism. The sending end is implemented by the information sending adapter class, which sends messages to the receiver through the message channel. The message handler adapter class in the sink is called to process the message. It invokes the receiver interface implemented by the receiver’s business logic. Any number of senders can send messages to a message channel, and likewise any number of receivers can receive messages from a message channel.
6. Summary
This paper is mainly a systematic introduction to microservice architecture, comparing the advantages and disadvantages of single application architecture and microservice architecture, and focusing on the aspects that need to be considered in the design of microservice architecture, such as service separation, communication mode, observability, security, deployment-related and other related modes. Finally, the policy and guiding principle of service splitting and the working principle of remote procedure call and message interaction are introduced.
reference
- Microservices Architecture Design Patterns
—————————————————————————————–
Thanks for your attention! Wechat official account (code color).