1. Understand microservices
1. Single structure
All the functions of the business are developed in one project and packaged into one package for deployment.
advantage
- simple structure
- Low deployment cost
shortcoming
- High coupling
[External link picture transfer failed, the source site may have an anti-leeching mechanism, it is recommended to save the picture and upload it directly (img-fPfsQXAn-1689593800699)(https://picture.wangkay.tech/blog/image-20230717100100447.png)]
2. Distributed architecture
The system is split according to business functions, and each business module is developed as an independent project, called a service
advantage
- reduce coupling
- Conducive to service upgrade and expansion
3. Microservices
Microservice is a distributed architecture solution with well-designed architecture. Microservice architecture features:
- Single responsibility: Microservice split granularity is smaller, each service corresponds to a unique business capability, so as to achieve a single responsibility and avoid repeated business development
- Service-oriented: Microservices expose business interfaces to the outside world
- Autonomy: independent team, independent technology, independent data, independent deployment
- Strong isolation: service calls are isolated, fault-tolerant, and degraded to avoid cascading problems
4. Microservice structure
The microservice solution requires a technical framework to implement it. Internet companies around the world are actively trying their own microservice implementation technology. The most well-known in China are SpringCloud and Alibaba's Dubbo.
5. Enterprise needs
二、SpringCloud
- SpringCloud is currently the most widely used microservice framework in China.
- SpringCloud integrates various microservice functional components, and realizes the automatic assembly of these components based on SpringBoot, thus providing a good out-of-the-box experience:
1. Service split
Considerations for Service Splitting
- Single responsibility: different microservices, do not develop the same business repeatedly
- Data independence: Do not access databases of other microservices
- Service-oriented: expose your business as an interface for other microservices to call
2. Remote call (query the order function according to the order id)
Requirement: While querying the order according to the order id, return the user information to which the order belongs
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-OxFyPehL-1689593800699)(https://picture.wangkay.tech/blog/image-20230717102926142.png)]
(1) Register RestTemplate
Register RestTemplate in OrderApplication of order-service
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
(2) The service calls RestTemplate remotely
Modify the queryOrderById method of OrderService in order-service:
@Service
public class OrderService {
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// TODO 2.查询用户
String url = "http://localhost:8081/user/" + order.getUserId();
User user = restTemplate.getForObject(url, User.class);
// 3.封装user信息
order.setUser(user);
// 4.返回
return order;
}
}
(3) The basic way of calling microservices
- Realize remote call based on http request initiated by RestTemplate
- Remote calls made by http requests are language-independent calls, as long as you know the other party's ip, port, interface path, and request parameters.
(4) Service call relationship
- Service provider: expose the interface to other microservice calls
- Service consumers: call interfaces provided by other microservices
- Provider and consumer roles are actually relative
- A service can be both a service provider and a service consumer
3. Eureka Registration Center
1. Introduction to Eureka
Eureka is an open source service registration and discovery component of Netflix, and it is one of the core tools for building a microservice architecture in a distributed system. The main goal of the Eureka registry is to achieve high availability, dynamic discovery and load balancing between services.
In the microservice architecture, the system is split into multiple small services, each of which runs in an independent process and cooperates with each other to provide the overall functionality of the system. These services need to be able to communicate and discover in a distributed environment, which is what the Eureka registry does.
The Eureka registry has two main components:
-
Eureka Server: It is the core of the registry and runs on one or more servers in the cluster. Each service (microservice application) will register its own information with Eureka Server, including service name, network address, health status, etc. Eureka Server maintains a service registry that records all registered service information.
-
Eureka Client: It is a microservice application. As a service consumer, it will register itself with Eureka Server and send heartbeats periodically to indicate its health status. At the same time, Eureka Client will also obtain the service registry from Eureka Server, and when it needs to call other services, it will obtain the information of the corresponding service from the registry to realize the communication between services.
The Eureka registry has the following main features:
-
High availability: Eureka Server supports running in a cluster to ensure the high availability of the registration center. Even if a node fails, other nodes can still provide service registration and discovery functions.
-
Dynamic discovery: Service registration and discovery are dynamic. When a new service goes online or offline, Eureka Server can sense and update the registry in time, so that other services can dynamically obtain the latest service information.
-
Load balancing: Eureka Client can implement load balancing according to the information in the service registry, so as to distribute requests among multiple available service providers and improve the scalability and performance of the system.
The Eureka registry plays an important role in Netflix's microservice architecture, and because of its open source nature, many other companies and developers have also adopted Eureka as a solution for service registration and discovery in their projects. It is worth noting that although Eureka has been widely used in the past, in the current technological development, other registry solutions with similar functions have also appeared, such as Consul, etcd, etc.
2. The role of Eureka
- How should consumers obtain specific information about service providers?
- The service provider registers its own information with eureka when it starts
- eureka saves this information
- Consumers pull provider information from eureka according to the service name
- If there are multiple service providers, how should consumers choose?
- The service consumer uses the load balancing algorithm to select a service from the service list
- How do consumers perceive the health status of service providers?
- The service provider will send a heartbeat request to EurekaServer every 30 seconds to report the health status
- eureka will update the record service list information, and the abnormal heartbeat will be removed
- Consumers can pull the latest information
In the Eureka architecture, there are two types of microservice roles:
- EurekaServer: server, registration center
- Record service information
- Heartbeat monitoring
- EurekaClient: client
- Provider: service provider, such as user-service in the case
- Register your own information to EurekaServer
- Send a heartbeat to EurekaServer every 30 seconds
- consumer: service consumer, such as order-service in the case
- Pull the service list from EurekaServer according to the service name
- Do load balancing based on the service list, and initiate a remote call after selecting a microservice
- Provider: service provider, such as user-service in the case
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-88TXJy2e-1689593800699)(https://picture.wangkay.tech/blog/image-20230717142428805.png)]
3. Build Eureka Server
The steps to build the EurekaServer service are as follows:
-
Create a project and introduce the dependency of spring-cloud-starter-netflix-eureka-server
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency>
-
Write the startup class and add @EnableEurekaServer annotation
To write a startup class for the eureka-server service, be sure to add a @EnableEurekaServer annotation to enable the registration center function of eureka:
package cn.itcast.eureka; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; @SpringBootApplication @EnableEurekaServer public class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); } }
-
Add the application.yml file and write the following configuration:
server: port: 10086spring: application: name: eurekaserver eureka: client: service-url: defaultZone: http://127.0.0.1:10086/eureka/
-
start service
Start the microservice, and then visit it in the browser: http://127.0.0.1:10086
See the following result should be successful:
4. Service registration
Next, we register user-service to eureka-server.
1) Introduce dependencies
In the pom file of user-service, introduce the following eureka-client dependencies:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2) Configuration file
In user-service, modify the application.yml file and add the service name and eureka address:
spring:
application:
name: userservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
3) Start multiple user-service instances
In order to demonstrate a scenario where a service has multiple instances, we add a SpringBoot startup configuration and start a user-service.
First, copy the original user-service startup configuration:
The above needs to check the Add VM option in the modification option and add it-Dserver.port=8082
Start two user-service instances:
4) Complete service pull in order-service
Service pull is to obtain the service list based on the service name, and then perform load balancing on the service list
-
Modify the code of OrderService, modify the url path to access, and use the service name instead of ip and port:
String url = "http://userservice/user/" + order.getUserId();
-
Add load balancing annotations to RestTemplate in the startup class OrderApplication of the order-service project :
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); }
Spring will automatically help us obtain the instance list from the eureka-server side according to the service name userservice, and then complete the load balancing.
4. Ribbon load balancing
1. The principle of load balancing
1)LoadBalancerIntercepor
The intercept method here intercepts the user's HttpRequest request, and then does several things:
request.getURI()
: Get the request uri, in this case it is http://user-service/user/8originalUri.getHost()
: Get the host name of the uri path, which is actually the service id.user-service
this.loadBalancer.execute()
: Process service id, and user requests.
Here this.loadBalancer
is LoadBalancerClient
the type, we continue to follow.
2)LoadBalancerClient
- getLoadBalancer(serviceId): Get ILoadBalancer according to the service id, and ILoadBalancer will take the service id to eureka to get the service list and save it.
- getServer(loadBalancer): Use the built-in load balancing algorithm to select one from the service list. In this example, you can see that the service on port 8082 has been obtained
3) Load balancing strategy IRule
4) Summary
The bottom layer of SpringCloudRibbon uses an interceptor to intercept the request sent by RestTemplate and modify the address. To sum it up with a picture:
The basic process is as follows:
- Intercept our RestTemplate request http://userservice/user/1
- RibbonLoadBalancerClient will get the service name from the request url, which is user-service
- DynamicServerListLoadBalancer pulls the service list from eureka according to user-service
- eureka returns the list, localhost:8081, localhost:8082
- IRule uses built-in load balancing rules, select one from the list, such as localhost:8081
- RibbonLoadBalancerClient modifies the request address, replaces userservice with localhost:8081, gets http://localhost:8081/user/1, and initiates a real request
2. Load balancing strategy
load balancing strategy
The rules of load balancing are defined in the IRule interface, and IRule has many different implementation classes:
The meanings of the different rules are as follows:
Built-in load balancing rule class | Rule description |
---|---|
RoundRobinRule | Simply poll the list of services to select a server. It is the default load balancing rule of Ribbon. |
AvailabilityFilteringRule | Ignore the following two servers: (1) By default, if this server fails to connect 3 times, this server will be set to the "short circuit" state. The short-circuit state will last for 30 seconds, and if the connection fails again, the duration of the short-circuit will increase geometrically. (2) Servers with too high concurrency. If the number of concurrent connections of a server is too high, the client configured with the AvailabilityFilteringRule rule will also ignore it. The upper limit of the number of concurrent connections can be configured by the ..ActiveConnectionsLimit property of the client. |
WeightedResponseTimeRule | Assign a weight value to each server. The longer the server response time, the less weight this server has. This rule will randomly select a server, and this weight value will affect the server selection. |
ZoneAvoidanceRule | Server selection is based on the servers available in the region. Use Zone to classify servers. This Zone can be understood as a computer room, a rack, etc. Then poll multiple services in the Zone. |
BestAvailableRule | Ignore servers that are short-circuited and choose servers with lower concurrency. |
RandomRule | Randomly select an available server. |
RetryRule | Selection logic for the retry mechanism |
The default implementation is ZoneAvoidanceRule, which is a polling scheme
Custom load balancing strategy
The load balancing rules can be modified by defining the IRule implementation. There are two ways:
- Code method: In the OrderApplication class in order-service, define a new IRule:
@Bean
public IRule randomRule(){
return new RandomRule();
}
- Configuration file method: In the application.yml file of order-service, adding new configurations can also modify the rules:
userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
Note that the default load balancing rules are generally used without modification.
3. Hunger loading
Ribbon uses lazy loading by default, that is, the LoadBalanceClient is created only when it is accessed for the first time, and the request time will be very long.
Hunger loading will be created when the project starts to reduce the time-consuming for the first visit. Enable hunger loading through the following configuration:
ribbon:
eager-load:
enabled: true
clients: userservice