SpringCloudAlibaba load balancer-Ribbbon

SpringCloudAlibaba load balancer-Ribbon


The code and notes of this project have been stored in the Gitee warehouse address: code, notes

1.What is Ribbon

Currently, the mainstream load balancing solutions are divided into the following two types:

  • Centralized load balancing uses independent agents to carry out load between consumers and service providers. There are hardware (such as F5) and software (such as Nginx).
  • The client does load balancing according to its own request situation, and Ribbon is the client's own load balancing.

SpringCloud Ribbon is a set of client-side load balancing tools implemented based on NetFlix Ribbon . The Ribbon client component provides a series of complete configurations, such as timeout, retry, etc. All machine instances provided by the server are obtained through Load Balancer, and Ribbon will automatically call these services based on certain rules (polling, random). Ribbon can also implement our own load balancing algorithm .

1.1 Client load balancing

For example, in the Ribbon in spring cloud, the client has a service address list. Before sending the request, it selects a server through the load balancing algorithm and then accesses it. At this time, the client is load balanced, that is, the load balancing algorithm is allocated on the client.

1.2 Server-side load balancing

For example, Nginx performs load balancing through Nginx. The request is sent first, and then the load balancing algorithm is used to select one of multiple servers for access; the load balancing algorithm can then be distributed on the server side.

1.3 Common load balancing algorithms

  • Random, which is executed by randomly selecting services. Generally, this method is rarely used.
  • Polling, the default implementation of load balancing, queues requests after they come in.
  • Weighted polling assigns higher weights to servers with high configuration and low load through server performance classification to balance the pressure of each server.
  • Address Hash, the server is scheduled through modulo mapping of the HASH value of the client request address. ip hash
  • The minimum number of links, the instant request load is balanced, the pressure will not necessarily be balanced. The minimum number of links algorithm is to allocate requests to the server with the lowest current pressure and the minimum active number based on the server's conditions, such as the number of request backlogs and other parameters.

2.Nacos uses Ribbon

1) nacos-discovery relies on ribbon, so there is no need to introduce ribbon dependencies.

ppP3UxS.png

2) Add the @LoadBalanced annotation

@Configuration
public class RestConfig{
    
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    
    
        return  new RestTemplate();
    }
}

3) Modify Controller

@RestController
@RequestMapping("/order")
public class OrderController {
    
    
    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/add")
    public String add() {
    
    
        System.out.println("下单成功");
        //在RestTemplate配置的时候加上了@LoadBalance启动负载均衡后就必须使用服务名进行调用了 如果使用ip端口调用则会报错
//        String msg = restTemplate.getForObject("http://192.168.13.1:8021/stock/reduct",String.class);
        String msg = restTemplate.getForObject("http://stock-service/stock/reduct", String.class);
        return "Hello word!" + msg;
    }
}

3.Ribbon load balancing strategy

3.1Rule interface

img

The floor

This is the parent interface of all load balancing strategies. The core method inside is the choose method, which is used to select a service instance.

IRule interface, Riboon uses this interface to select a service from all services according to a specific algorithm. The IRule interface has 7 implementation classes . Each implementation class represents a load balancing algorithm. Polling is used by default.

AbstractLoadBalancerRule

AbstractLoadBalancerRule is an abstract class, which mainly defines an ILoadBalancer. The purpose of defining it here is mainly to assist in selecting the appropriate server instance for the balancing strategy.

1.RandomRule

As you can tell from the name, this load balancing strategy is to randomly select a service instance . Looking at the source code, we know that a Random object is initialized in the parameterless constructor of RandomRule, and then the choose(ILoadBalancer) method is called in the overridden choose method. lb, Object key) This overloaded choose method, in this overloaded choose method, uses the random object to generate a random number that is not greater than the total number of service instances each time, and uses this number as a subscript to obtain a service instance.

2.RoundRobinRule

The load balancing strategy of RoundRobinRule is called linear round robin load balancing strategy . The overall logic of the choose(ILoadBalancer lb, Object key) function of this class is as follows: turn on a counter count, traverse the service list in the while loop, and obtain a subscript through the incrementAndGetModulo method before obtaining the list. This subscript is a continuous automatic The increasing number is obtained after adding 1 first and then modulo the total number of service lists (so this subscript will never cross the boundary). Take the subscript and then go to the service list to get the service. The counter will be incremented every time it loops.

1. If the service is not obtained for 10 consecutive times, a warning No available alive servers after 10 tries from load balancer: XXXX will be reported.

3.RetryRule (retry based on polling)

As you can see from the name, this load balancing strategy has a retry function. First, a subRule is defined in RetryRule, and its implementation class is RoundRobinRule. Then in the choose(ILoadBalancer lb, Object key) method of RetryRule, the choose rule in RoundRobinRule is still used to select a service instance each time. If the selected If the instance is normal, it will be returned. If the selected service instance is null or has expired, it will be retried continuously before the expiration time deadline (the strategy for obtaining the service during retry is still the strategy defined in RoundRobinRule). If the deadline is exceeded, it is still not retrieved. will return a null.

4.WeightedResponseTimeRule (weight—NacosRule of nacos, Nacos also extends a own configuration-based weight extension)

WeightedResponseTimeRule is a subclass of RoundRobinRule. The functions of RoundRobinRule are extended in WeightedResponseTimeRule. WeightedResponseTimeRule will calculate a weight of each instance based on its running status, and then select the instance based on the weight . , which can achieve better instance calling. There is a scheduled task named DynamicServerWeightTask in WeightedResponseTimeRule. By default, the weight of each service instance is calculated every 30 seconds. The weight calculation rule is also very simple. If the average response time of a service is shorter, the weight will be greater, then The probability that the service instance is selected to perform the task is also greater .

5.BestAvailableRule

BestAvailableRule inherits from ClientConfigEnabledRoundRobinRule. Based on ClientConfigEnabledRoundRobinRule, it mainly adds the function of filtering out failed service instances based on the status information of the service instances saved in loadBalancerStats, and then finds the service instance with the smallest concurrent requests for use. **However, loadBalancerStats may be null. If loadBalancerStats is null, BestAvailableRule will adopt the service selection strategy (linear polling) of its parent class, ClientConfigEnabledRoundRobinRule.

6.ZoneAvoidanceRule ( Default rule , which combines the performance of the zone where the server is located and the availability of the server to select the server.)

ZoneAvoidanceRule is an implementation class of PredicateBasedRule, but there is one more filter condition here. The filter condition in ZoneAvoidanceRule is a combined filter condition called CompositePredicate, which is composed of ZoneAvoidancePredicate as the main filter condition and AvailabilityPredicate as the secondary filter condition. After the filtering is successful, continue Use linear polling ( RoundRobinRule ) to select one from the filtered results.

7.AvailabilityFilteringRule (First filter out faulty instances, then select instances with smaller concurrency) Filter out backend servers marked as circuit tripped that have always failed to connect, and filter out those high-concurrency backend servers or use an AvailabilityPredicate to include them The logic of filtering servers is actually to check the running status of each server recorded in status.

3.2 Modify the default load balancing policy

Global configuration: When calling other microservices, always use the specified load balancing algorithm

@Configuration
public class RibbonRandomRuleConfig {
    
    
    @Bean
    public IRule iRule() {
    
    
        return new RandomRule();
    }
}

Note: There is a pit here. It cannot be written in a place scanned by @CompentScan annotated with @SpringbootApplication, otherwise the custom configuration class will be shared by all RibbonClients. It is not recommended to use it this way. The yml method is recommended.

Use @RibbonClient to specify microservices and their load balancing strategies.

@SpringBootApplication
@EnableDiscoveryClient   //启动nacos的客户端 不加也行在后续的版本这个注解可不用手动添加
@RibbonClients(value = {
    
    
        // 在SpringBoot主程序扫描的包外定义配置类
        @RibbonClient(name = "stock-service", configuration = RibbonRandomRuleConfig.class)
     
})
public class OrderApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(OrderApplication.class, args);
    }

    @Bean
    @LoadBalanced   //负载均衡注解,加上后就必须使用服务名调用
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
    
    
        RestTemplate restTemplate = builder.build();
        return restTemplate;
    }


}

Use the configuration file method : When calling the services provided by the specified microservice, use the corresponding load balancing algorithm (you must comment out the @RibbonClients above first, otherwise it will conflict). Pay attention to the superior-subordinate relationship of the configuration.

Modify application.yml

1 # 被调用的微服务名
2 mall‐order:
3  ribbon:
4  # 指定使用Nacos提供的负载均衡策略(优先调用同一集群的实例,基于随机&权重)
5    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule

3.3 Customized load balancing strategy

The load strategy can be customized by implementing the IRule interface, and the main service selection logic is in the choose method.

Modify startup class

public class CustomRule extends AbstractLoadBalancerRule {
    
    
    private static final Logger logger = Logger.getLogger("CustomRule.class");
    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Override
    public Server choose(Object key) {
    
    
        DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) getLoadBalancer();
        String serviceName = loadBalancer.getName();
        NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
        try {
    
    
            //nacos基于权重的算法
            Instance instance = namingService.selectOneHealthyInstance(serviceName);
            return new NacosServer(instance);
        } catch (NacosException e) {
    
    
            logger.info("获取服务实例异常:{}" + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public void initWithNiwsConfig(IClientConfig clientConfig) {
    
    

    }
}

Modify configuration class

@SpringBootApplication
@EnableDiscoveryClient   //启动nacos的客户端 不加也行在后续的版本这个注解可不用手动添加
@RibbonClients(value = {
    
    
        // 在SpringBoot主程序扫描的包外定义配置类
//        @RibbonClient(name = "stock-service", configuration =  RibbonRandomRuleConfig.class)
        @RibbonClient(name = "stock-service", configuration = CustomRule.class)
})
public class OrderApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(OrderApplication.class, args);
    }

    @Bean
    @LoadBalanced   //负载均衡注解,加上后就必须使用服务名调用
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
    
    
        RestTemplate restTemplate = builder.build();
        return restTemplate;
    }

}

3.4 Hungry loading

When making service calls, if the network condition is not good, the first call will time out.

Ribbon is lazy loaded by default, which means that the client is only created when a call is made.

Enable hungry loading to solve the problem of slow first call

ribbon:
  eager-load:
    enabled: true # 开启饥饿加载
    clients:  # 指定饥饿加载的服务名称
      - stock-service

4.LoadBalancer

What is Spring Cloud LoadBalancer?

Spring Cloud LoadBalancer is the client load balancer officially provided by Spring Cloud itself, used to replace

Ribbon。

Spring officially provides two load balancing clients:

RestTemplate

RestTemplate is a client provided by Spring for accessing Rest services. RestTemplate provides a variety of convenient access

The remote HTTP service method can greatly improve the writing efficiency of the client. By default, RestTemplate relies on

HTTP connection tool for jdk.

WebClient

WebClient is a non-blocking reactive programming-based Http request provided starting from Spring WebFlux 5.0.

Client tools required. Its reactive programming is based on Reactor. WebClient provides standard HTTP request methods for

The corresponding get, post, put, delete and other methods can be used to initiate corresponding requests.

2. RestTemplate整合LoadBalancer

1) Introduce dependencies

 <!‐‐ LoadBalancer ‐‐>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐loadbalancer</artifactId>
</dependency>

<!‐‐ 提供了RestTemplate支持 ‐‐>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐web</artifactId>
</dependency>

<!‐‐ nacos服务注册与发现 移除ribbon支持‐‐>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring‐cloud‐starter‐alibaba‐nacos‐discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring‐cloud‐starter‐netflix‐ribbon</artifactId>
</exclusion></exclusions>
</dependency>

Note: Ribbon is introduced in nacos-discovery, and the ribbon package needs to be removed.

If you do not want to remove it, you can also configure it in yml not to use the ribbon.

spring:
  application:
  name: order-service
  cloud:
  nacos:
  discovery: 
  server‐addr: 127.0.0.1:8848
  # 不使用ribbon
    loadbalancer:
    ribbon:
    enabled: false

2) Configure RestTemplate using @LoadBalanced annotation

 @Configuration
 public class RestConfig {
    
    
  @Bean
  @LoadBalanced
 public RestTemplate restTemplate() {
    
    
 return new RestTemplate();
 }
 }

3) Use

@RestController
@RequestMapping("/order")
public class OrderController {
    
    
    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/add")
    public String add() {
    
    
        System.out.println("下单成功");
        //在RestTemplate配置的时候加上了@LoadBalance启动负载均衡后就必须使用服务名进行调用了 如果使用ip端口调用则会报错
//        String msg = restTemplate.getForObject("http://192.168.13.1:8021/stock/reduct",String.class);
        String msg = restTemplate.getForObject("http://stock-service/stock/reduct", String.class);
        return "Hello word!" + msg;
    }
}

Guess you like

Origin blog.csdn.net/qq_45925197/article/details/129548755