微服务LoadBalancer使用手册

111 阅读2分钟

由于Netflix Ribbon组件停止更新,所以Spring Cloud官方自研LoadBalancer用来替代Ribbon,提供客户端负载均衡器抽象和实现。

01 Ribbon和LoadBalancer对比

LoadBalancer主要优势是支持响应式编程方式异步访问客户端,依赖Spring Web Flux实现客户端负载均衡调用。

组件负载均衡策略支持的客户端
Netflix Ribbon「随机」RandomRule
「轮询」RoundRobinRule
「重试」RetryRule
「最低并发」BestAvailableRule
「可用过滤」AvailabilityFilteringRule
「响应时间加权重」ResponseTimeWeightedRule
「区域权重」ZoneAvoidanceRule
Feign、 Openfeign、 RestTemplate
Spring Cloud LoadBalancer「随机」RandomLoadBalancer
「轮询」RoundRobinLoadBalancer
Ribbon支持的客户端、 WebClient

02 整合LoadBlance

如果Hoxton之前版本,默认负载均衡器为Ribbon,需要移除Ribbon引用和增加配置spring.cloud.loadbalancer.ribbon.enabled: false

2.1 升级版本

Spring Cloud AlibabaSpring cloudSpring Boot
2.2.6.RELEASEHoxton.SR92.3.2.RELEASE

2.2 添加LoadBalance依赖

<!-- Nacos服务注册发现 -->
<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><!-- 添加LoadBalanncer依赖, 添加Spring Cloud依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

03 自定义负载均衡器

public class CustomRandomLoadBalancerClient implements ReactorServiceInstanceLoadBalancer {
    // 服务列表
    private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
 
    public CustomRandomLoadBalancerClient(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
    }
 
    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();
        return supplier.get().next().map(this::getInstanceResponse);
    }
 
    // 随机数获取服务
    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
        System.out.println("已接收到请求");
        if (instances.isEmpty()) {
            return new EmptyResponse();
        }

        System.out.println("随机选取服务");
        // 随机算法
        int size = instances.size();
        Random random = new Random();
        ServiceInstance instance = instances.get(random.nextInt(size));
        return new DefaultResponse(instance);
    }
}
@EnableDiscoveryClient
@SpringBootApplication
// 设置全局负载均衡器
@LoadBalancerClients(defaultConfiguration = {CustomRandomLoadBalancerClient.class})
// 指定具体服务负载均衡
//@LoadBalancerClient(name = "stock",configuration = CustomRandomLoadBalancerClient.class)
//@LoadBalancerClients(
//    value = {@LoadBalancerClient(value = "stock", configuration = CustomRandomLoadBalancerClient.class)},
//    defaultConfiguration = LoadBalancerClientConfiguration.class
//)
public class OrderApplication {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class);
    }
}

04 重试机制

spring:
  cloud:
    loadbalancer:
      # 以下为LoadBalancerProperties配置类
      clients:
        # default表示全局配置,指定服务名称即可配置某个服务
        default:
          retry:
            enbled: true
            # 是否所有请求都重试, false表示只有GET请求才重试
            retryOnAllOperation: true
            # 同一个实例重试次数, 不包括第一次调用, 比如第填写3实际会调用4次
            maxRetriesOnSameServiceInstance: 3
            # 其他实例重试次数, 多节点情况使用
            maxRetriesOnNextServiceInstance: 0