1. The nature of microservices

Microservices architecture is essentially a distributed architecture, not so much a new architecture as a micro-architecture

Business architecture style.

To put it simply, the microservice architecture style is about developing an application that consists of many small services. Each service runs in a separate process and uses lightweight interaction. In most cases it is an HTTP resource API. These services have independent business capabilities and can be deployed independently through automated deployment. This style enables centralized management of minimization, allowing for the use of many different programming languages and data storage technologies.

For the microservice architecture system, due to its small service granularity and clear modularization, the first thing to do is to plan the functions and services of the system as a whole, and give priority to how to organize the whole process of code structure, configuration, testing, deployment, operation and maintenance and monitoring from engineering practice in the delivery process. Thus, the independence and deployability of microservices are effectively reflected.

In this paper, the design stage, development stage, test stage and deployment stage of microservice system will be comprehensively described.

Understanding the microservices architecture and philosophy is central.

2. System environment

3. Challenges of microservices architecture

Reliability:

As a result of remote invocation, service invocation will fail if any node or network has problems. As the number of microservices increases, potential failure points will also increase.

In other words, without adequate safeguard mechanism, the single point of failure will increase greatly.

High operation and maintenance requirements:

System monitoring, high availability, automation technology

Distributed complexity:

Network latency, system fault tolerance, distributed transactions

Strong deployment dependency:

Service dependency, multi-version issues

Performance (high cost of communication between services) :

Stateless, interprocess invocation, cross-network invocation

Data consistency:

Distributed transaction management, which spans multiple nodes to ensure instantaneous consistency of data, is much more expensive than traditional single architecture transactions. In addition, in distributed systems, the final consistency of data is usually considered to solve the system unavailability caused by instantaneous data consistency.

Repeated development:

The concept of micro-service advocates that each micro-service is treated as a product, and it can be developed by its own team, or even has its own completely different technology and framework. Then the sharing of technology with other micro-service teams will lead to conflicts, resulting in repetitive development work.

4. Architecture design

4.1. Thinking design

The fundamental purpose of microservice architecture design is to achieve value delivery. Microservice architecture can be smoother only by following the concept of *DevOps*, and the change of thinking mode is the most important.

To realize the technical architecture of micro-services, the existing products need to be improved in technology and the implementation of related supporting services, and the strategies for implementing segments and pilot products are mainly included as follows:

I. Technical improvement:

1. The front and back ends are separated. The Web front end invokes the API gateway of microservice through Http/Https protocol, and the API gateway invokes the corresponding microservice through routing service

2. Different microservices call each other through REST

3. Message interaction mechanism is realized between micro-services through message middleware

Ii. Supporting Services and Functions:

1. Corresponding automatic service implementation is required, including automatic construction, automatic installation and deployment, automatic testing and automatic platform release (Docker implementation)

2. Management services. For the micro-service architecture, corresponding monitoring and management services and log management services must be supported

3. Collaborative services, using DevOps to improve the efficient communication and collaboration of development, testing, operation and maintenance, and realize the integration of development and operation and maintenance

4.3. Design of micro-service architecture

1. We divide the whole system into several subsystems or microservices based on business.

2. Each subsystem can deploy multiple applications, and load balancing is used among multiple applications.

3. A service registry, Eureka, is required. All services are registered in the registry, and load balancing is implemented by using certain policies for services registered in the registry. ****Eureka**** Multiple Eureka can be deployed to ensure high availability.

4, all clients access the background service through the same gateway address, through the route configuration ZUUL gateway to determine a URL request by which service processing. Use the load balancing Ribbon when forwarding requests to services.

5. Call between services using Feign.

6. Use the circuit breaker Hystrix to deal with timeouts and errors during service invocation in a timely manner, preventing the whole system from crashing due to a problem with one of the services.

7. You also need a monitoring function to monitor how long each service invocation takes, etc.

8. For unified configuration management using SpringCloud Config, consider how it works with the company’s configuration management platform.

9. Hystrix, Monitoring and Circuit breakers. We just need to add the Hystrix tag to the service interface, and we can implement the monitoring and circuit breaker function of this interface.

Hystrix Dashboard, which provides an interface to monitor the time consumed by service calls on individual services, etc.

11. Turbine, monitor aggregation. With Hystrix monitoring, we need to open the monitoring information of each service instance to check. Turbine can help us aggregate the monitoring information of all service instances into one place for unified viewing.

So you don’t have to go from page to page.

Architecture reliability assurance:

Key nodes are deployed in active/standby mode or in clusters to prevent single points of failure.

Questions to be confirmed:

1. Access Control: Zuul gateway provides relevant Control functions. How to use it in combination with CAS of our company

2. Config Server: Spring Cloud provides a remote configuration center. How can it be used together with our configuration management platform

5. Design phase

5.1. Overall design

1. Function planning: Split product functions into several micro-services; A single feature can create multiple microservices and deploy them on multiple server nodes for load balancing.

2. Design the atomic service layer, sort out and extract core applications and public applications, and sink into the core and public capability layer as independent services, gradually form a stable service center, so that applications can respond to changing customer needs more quickly.

3. Design *API* interfaces for each service (REST)

4. Classify different services. Different services require different resources, and you can configure different resources, including CPU, memory, and storage.

5.2. Principle of service separation

*1*, small particle size:

Service granularity is divided according to service functions. The general principle is high cohesion within services and low coupling between services.

*2*, single responsibility:

Each service does one thing, the single responsibility principle.

*3* Principle of isolation:

Each service is isolated from the other and does not affect each other

*4*, business independent priority principle:

Basic services, which are basic components, are not business specific. For example: SMS service, email service. The services here are the easiest to divide into microservices and are our first priority for separation.

5.3. Service planning

To achieve load balancing, the same service can register with the same service name and different ports on multiple nodes. Without prior planning, different service providers may register the same service name, causing confusion when consumers invoke the service.

Therefore, unified planning of service names is required:

1. Make the service name or module label of each service provider in the planning period.

2. The naming rule of the service name is ModuleName_ServiceName. All characters are lowercase and different words are separated by an underscore. If the user management module provides the service of obtaining user information, the user name is user_get_info.

3. When adding a service name, you need to submit an application and use it only after approval. In order to reduce the complexity of approval, only ModuleName can be approved, that is, the service name can be added freely within the module without approval.

There is no best, only the most suitable for their own.

5.4. Development strategy

General rule: Different microservices need to be physically isolated.

1. SVN policy: Create an independent branch on SVN, and the code submission of different microservices is not affected by each other;

****– **** Centrally controlled by the configuration administrator.

Problem: Development branch and integration branch, will increase a lot of maintenance workload.

2. Compilation strategy: During code compilation, each microservice is compiled and packaged independently, eliminating direct dependence;

3. Engineering construction: During code development, each microservice is created as an independent project, and direct dependence between projects cannot be generated

Continuous integration: Each microservice performs continuous integration independently.

5. Version integration: Automatic version integration is realized by a unified integration tool, and all microservices are integrated into a unified version distribution package.

5.5. Version policy

Each microservice can be independently developed. As the number of services increases, SVN branches and versions also increase, and the complexity of version management increases exponentially. When there are many dependencies between services, the upgrade or degradation of each service will affect the normal operation of other services.

Therefore, the following policies need to be implemented:

1. Version making of all services shall be carried out by professional version manager.

2, the use of automated version production strategy, minimize manual operation.

3. Each service version must have a detailed version plan and description. For the version description, make a template and specify the content to be submitted, version number, and SVN label.

4. To improve the requirements of the project manager, the overall version plan should be strictly formulated, especially the dependency between versions should be very clear, and the risk assessment of version upgrade and downgrade should be completely sufficient.

5, interface management: strictly implement the interface management system, any interface change must be approved, announcement and other processes.

5.6. Database challenges and strategies

Each microservice has its own independent database, so how to deal with the joint query of backstage management? This should be a common problem, and there are three ways to deal with it.

1) Strictly follow the division of microservices. Microservices are independent of each other and each microservice database is also independent. When the background needs to display data, the interface of each microservice is called to obtain the corresponding data, and then the data is processed and displayed, which is the standard and most troublesome usage.

  1. It is a compromise solution to put the tables that are highly related to business into one library and split the tables that are not closely related to business in strict accordance with the microservice mode. In this way, microservice can be used and the statistical function of background system is difficult to be realized due to the scattered database.

3) The database is segmented strictly in accordance with the requirements of micro-services to meet the high concurrency of services. Data of micro-services database is synchronized to the NoSQL database in real time or quasi-real time. Data cleaning is performed during the synchronization to meet the requirements of background service systems.

The first scheme is suitable for small companies with relatively simple business; The second option is suitable for companies that gradually evolve into microservices architecture on top of the original system. The third is suitable for large, highly concurrent Internet companies.

It is suggested that we adopt the second option at present.

5.7. Load balancing

Instead of adding Load Balancing servers, such as F5, Nginx, and LVS, Load Balancing functions are integrated into the processes of service consumers in the way of libraries. This scheme is called Soft Load Balancing or client Load Balancing. With Eureka’s service registry in Spring Cloud, the Ribbon sub-project implements load balancing for REST clients.

Load balancing using the Ribbon can be summarized in the following four steps:
1. The Ribbon first selects a Low-load Eureka Server based on its Zone.
2. Periodically update and filter the list of service instances from Eureka Server;
3. Selects the address of a service instance from the list of available servers based on the specified load balancing policy ;
4 The service invocation is then made through RestClient.

The Ribbon itself provides the following load balancing strategies:

RoundRobinRule: Round policy. The Ribbon selects servers in round mode. This is the default. So the two services started in the example are accessed in a loop;

This means that the Ribbon will randomly select one from the list of servers to access

BestAvailableRule: The maximum available policy, that is, after the faulty server is filtered out, select the one with the smallest number of concurrent requests.

WeightedResponseTimeRule: with weighted polling strategy, weighted for each server response time, and then adopt the way of polling to obtain the corresponding server;

AvailabilityFilteringRule: available filtering strategy, to filter out the fault of part of the service instance or concurrent requests is greater than the threshold, and then, in the form of linear polling choose one from the filtered list of instance;

ZoneAvoidanceRule: Regional awareness strategy, first use master filter conditions (area load, select the optimal area) for all instances after filter and returns an instance of the list, in turn, use time filter condition in the list of filter to filter the results of the main filter conditions, determine the minimum number of filter (default 1) filter and minimum percentage (0) by default, Finally, RoundRobinRule is used to select a server instance if the conditions are met.

5.8. Performance policies

1. Network optimization: optimize the network structure and improve the communication performance between networks;

2. Configuration optimization: Optimize the configuration information of The Spring Cloud component set and other components to maximize performance.

5.9. Technology management strategy

It is pointed out in the architecture concept of micro-services that each micro-service can be built independently and can use different technologies, languages and frameworks, so that new technologies and frameworks can be used more quickly to respond to specific customer needs and solve the difficulties or obstacles faced by single application architecture to update technologies and frameworks.

However, it also brings many problems, as follows:

1. Can each service freely use its own technology, components and frameworks? If so, it is bound to bring greater difficulties in management, maintenance and technology sharing.

2. How can common methods be shared? If a simple way to format time needs to be shared, does it also need to be encapsulated as a service interface?

Management Strategy:

1. General principle: Overall consideration is still needed, all components are managed uniformly, and components are placed in the product warehouse. When each product or service needs to share components, they are obtained from the product warehouse.

2. Special circumstances: Special services need to use special components and frameworks, so it is necessary to submit applications and make overall planning before making decisions.

6. Development phase

6.1. Invocation of services

6.1.1. AIP gateway invocation

All services are invoked through the Zuul gateway and direct invocation of the microservice provider is not allowed.

Zuul can be a system bottleneck. In complex projects, it can be used for primary/secondary or load balancing.

6.1.2. Synchronous invocation

The HTTP REST method is used to implement load balancing based on service requirements. There are two methods for invoking load balancing:

1、 FeignClient

2、 RestTemplate

You are advised to use ****FeignClient**** to invoke the service.

Either way, it calls the HTTP interface of the service through the REST interface, and the parameters and results are serialized and deserialized by Jackson by default. Because of the interface defined by Spring MVC’s RestController, the returned data is serialized into JSON data by Jackson.

6.1.3. Asynchronous invocation

RabbitMq, Kafka, and Spring Cloud Stream are all alternatives.

Spring Cloud Stream, a messaging microservice based on Redis, Rabbit and Kafka, is a simple declaration model for sending and receiving messages in Spring Cloud applications.

6.1.4. Permission verification for inter-service calls

Generally, our API interface requires some kind of authorization to access. After a successful login, the interface can be invoked through token or cookie. With the Spring Cloud Netfix framework, the login request will be forwarded to the corresponding user service during login. After login, cookies or header tokens will be set. Subsequent requests from the client then carry the authentication information from the Zuul gateway to the corresponding service for authentication.

When the Zuul gateway forwards requests to the background service, it sends some headers to the server by default, such as Cookie, set-cookie, and Authorization. In this way, the headers requested by the client can be passed to the server, and the cookie set by the server can also be passed to the client.

However, if you want to disable certain headers from passing through to the server, you can do this in the Zuul gateway’s application.yml configuration:

As mentioned earlier, one of our services sometimes needs to call another service, when the request is not made by the client, and there is no authentication information in the header of the request. At this time, either through firewall and other Settings to ensure that the interface between services can only be accessed from a few addresses; Or you can set the header in some way.

Also, if you want to get the actual IP address of the request from a service (because the request is Forwarded through the gateway, you get the IP address of the gateway directly through the request), you can get it from headerx-Forwarded-host. If you want to disable the header, you can also:

If you use the RestTemplate method, you can add a header Options to the request. It can also be set using the following interceptor, which works with both the RestTemplate and FeignClient methods:

@Bean public RequestInterceptor requestInterceptor() { return new RequestInterceptor() { @Override public void apply(RequestTemplate template) { String authToken = getToken(); template.header(AUTH_TOKEN_HEADER, authToken); }}; }Copy the code

6.1.5. Service Orchestration

The main effect is to reduce interdependencies in the project. For example, now project A calls project B, and project B calls project C… All the way up to H, it is a call chain, so when the project goes online, it needs to update the bottom H first and then update g… Update C update B and finally update project A. This is just one call chain, and there are so many calls in a complex business that keeping in mind each call chain is a disaster for the shipping and maintenance staff.

A good way to minimize project interdependence is service choreography, a core business processing project that deals with microservices. For example, a used to call B, B used C, and C called D. Now it is handled in a core project W. When W service uses A, it calls B, and when W service uses B, it calls C.

In fact, it can be understood as object-oriented design, which reduces layer upon layer of nested calls between methods, and adopts a method to connect business processes in series. For example, method W realizes a complete business process, the following method is adopted:

The function w ()

{

1. Call method A;

2. Call method B;

3. Call method C;

}

6.2. Fusing treatment of services

When invoking between services, a mechanism is needed to protect against the spread of faults caused by exceptions such as remote service unavailability or pressure overload due to various reasons. Spring Cloud solves this problem with Netflix’s Hystrix component that implements fusing and downgrading. A Cricuit Breaker is a device that automatically fuses (opens switches) when remote services are unavailable and automatically restores (closes switches) when remote services are restored. Spring Cloud provides circuit breakers, resource isolation, and self-healing capabilities through Netflix’s Hystrix component.

6.3. Unified Log Management

When different microservices are deployed on different nodes, it is troublesome to log in to each node to view logs. Moreover, it is even more troublesome to associate multiple microservices logs for joint view and analysis. As the number of nodes increases, the complexity of locating and discovering problems increases exponentially without proper management mechanisms and tools. Therefore, unified log management is required.

1. Establish unified log management standards;

2. Develop and use a unified logging component to provide a unified logging service for all microservices, encapsulated by Log4j or Blitz4j;

3. Deploy the log collection Agent on each service node to collect and forward logs.

4. Create a unified log center and write all logs to the log center.

Note: The above log is realized by the company’s “Log Management platform”, using the ELK set framework.

6.4. Unified monitoring and management

Hystrix components are used to monitor services, and Nagios is used to monitor resources such as servers.

1. Hystrix, Monitoring and circuit breakers. We just need to add the Hystrix tag to the service interface, and we can implement the monitoring and circuit breaker function of this interface.

2. Hystrix Dashboard, which provides an interface to monitor the time consumed by service calls on various services, etc.

3. Turbine, monitor aggregation. With Hystrix monitoring, we need to open the monitoring information of each service instance to check. Turbine can help us aggregate the monitoring information of all service instances into one place for unified viewing.

So you don’t have to go from page to page.

6.5. Unified Configuration management

The company’s configuration management platform or SpringCloud Config configuration center can be used to realize unified parameter configuration and version management of various micro-services.

Pring Cloud Config is our usual configuration center. Spring Cloud Config- Extracts the configuration of an application from a local file and places it on a central server, essentially migrating the configuration information from the local to the Cloud. Thus, it can provide better management and publishing capabilities.

Spring Cloud Config consists of a server and a client. The server releases the configuration file stored in Git (SVN) to the REST interface. The client can obtain the configuration from the REST interface on the server. However, clients are not actively aware of configuration changes to obtain new configurations, requiring each client to trigger its own /refresh via POST. In order to ensure that the configuration information can be notified to each service in time and reduce the complexity of updating the configuration information of each micro-service,

To solve this problem, we use message bus as follows:

1. Git repository, Config Server And instances of microservices “Service A” and “Service B”
Spring Cloud Bus was introduced So they’re all connected RabbitMQ’s message bus.
2. From configuration changes in Git repository to initiating /bus/refresh The POST request step can be passed Git repository
3. /bus/refresh Instead of sending requests to specific service instances, the request is sent to Config Server and pass
destination Parameter to specify the service or instance whose configuration needs to be updated.
4. Since all applications connected to the message bus will receive the update request, the You don’t need it in WebHook
Maintain all node content to be updated, thus resolving the pass Web Hook to refresh one by one.

6.6. Distributed Session

Redis is used as the cache component and the shared component of session.

6.7. REST Resource response structure

Develop specifications and analytical methods.

6.8. API call chain tracing

Spring Cloud Sleuth’s main function is to provide tracking solutions in distributed systems, and it is compatible with Zipkin support. You just need to introduce the corresponding dependencies in the POM file.

6.9. Unit testing

In order to ensure product quality, development and test efficiency, unit test is essential.

Mock test emulation and continuous integration automate the execution and output of unit tests.

6.10. Code debugging

For a single architecture system, you can directly localize debugging, but for a microservice architecture, the call between interfaces needs to be remote communication, that is, the service to be called must be started before it can be called. Therefore, when the number of microservices increases, you may need to start a large number of microservices or Web servers. This makes local calls and debugging difficult.

Solutions need to be studied.

7. Test

7.1. Automated testing

Unit tests:

Implemented by developers.

Mock test simulation, continuous integration to automate the execution of unit tests and output results.

Business test:

Development to implement, testing also need to consider how to implement. To connect multiple services or business units in series to test a complete business or even a system test composed of different businesses, relevant automation testing frameworks, such as RobotFramework automation testing framework, should be adopted.

7.2. Dependency testing

It can also be called interface test or contract test. In the case of the gradual increase of micro-services, how to effectively ensure that services can work normally according to the interface agreement, that is, to comply with the contract, has become the main challenge faced by the testing in the implementation of micro-services.

1. Develop automated interface testing tools

1. Check whether the interface meets the convention

2. Check whether the interface changes

3. Check whether the interface can be called normally.

Ii. Test method:

Consumer-driven contract testing was adopted with the following test architecture:

Its advantages are as follows:

From the view of value and define contracts from the perspective of consumers to use contract, first ensure that consumers can realize value is based on the contract, with this premise, again use contract to verify the provider, if the provider’s contract with the definition of contract is consistent, is proved that the provider contract can achieve the service consumer. In this way, it focuses more on how to realize value.

Isolating consumer and provider testing For contract consumers and providers can be separated and tested independently, effectively solving the disadvantages of traditional integration testing service architecture and minimizing the interface testing cost of microservices.

Three, test tools:

*Pact*, *Janus*, ****Pacto****, etc.

7.3. System test

7.4. Fuse test

1. Test the correctness of the service route by stopping the microservice

2. Through the pressure test, overload and other abnormalities will occur in a micro-service, and the test service will be fused or degraded

3. Pass the stress test to test the correctness of the load balancing policy

7.5. Performance test

The original localized API calls will become REST remote calls, which will inevitably affect the call speed. Therefore, system performance needs to be considered and tested. The main influencing factors are as follows:

1. Network: The remote call is affected by the network communication speed, which involves the network speed, network deployment and system architecture. The principle of nearby deployment should be adopted for services with mutual dependence.

2. Server: Affected by the performance of the server where the remote service resides.

3. Data volume: Data volume refers to the size of data and the number and frequency of data transmission. At this time, the bottleneck will occur in REST invocation.

8. Continuous integration

1. Continuous integration: Each microservice performs continuous integration independently.

2, version integration: by the unified integration tool, to achieve automatic version integration, integrate all microservices into the unified

In the release package.

3. Continuous integration can produce versions of various scenarios, including test environment, development environment and production environment.

4. Statistical test coverage and other indicator data.

5, tools: Jenkins, Sonar, etc.

9. Continuous deployment

1. Make Docker images of released versions automatically through continuous integration;

2 Automatically upload the Docker image to the Docker container.

10. Operation and maintenance

10.1. Remote upgrade

The increasing number of microservices means that deployment containers are also increasing, and the workload for subsequent upgrade and maintenance will gradually increase. Developing a unified management center that supports remote maintenance and upgrade will reduce the complexity of o&M.

10.2. Unified Configuration center

Use Spring Cloud Config or configuration management platform for unified configuration management.

10.3. Unified Log Center

Use the log management platform to collect and analyze logs in a unified manner.

This article was first published on the public account: Java Version of the Web project, welcome to pay attention to get more exciting content