由于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 Alibaba | Spring cloud | Spring Boot |
|---|---|---|
| 2.2.6.RELEASE | Hoxton.SR9 | 2.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