系列文章:
Spring Cloud LoadBalancer之负载均衡简介
Spring Cloud NamedContextFactory 原理分析
Ribbon 的替代品 Spring Cloud Loadbalancer 使用与原理分析
本文的 spring-cloud-loadbalancer 版本为:3.1.1
由于 Ribbon 已经停更,Spring Cloud 在 Hoxton.M2 Released 版本将 Ribbon 剔除,并使用 Spring Cloud Loadbalancer 作为其替代品;
二者区别:
组件 | 组件提供的负载策略 | 支持负载的客户端 |
---|---|---|
Ribbon | 轮询、随机、重试策略、权重优先策略、 BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务 AvailabiliyFilteringRule:先过滤掉故障实例,再选择并发较小的实例 ZoneAvoidanceRule:默认规则,复合判断server所在区域的性能和server的可用性选择服务器 |
feign或openfeign、RestTemplate等 Web 调用工具 |
Spring Cloud Loadbalancer | 轮询、随机 | Ribbon 所支持的、WebClient |
LoadBalancer 的优势主要是,支持响应式编程的方式异步访问客户端,依赖 Spring Web Flux 实现客户端负载均衡调用。
一、 使用方法
使用方法很简单,只需要给需要负载均衡的 bean 添加 @LoadBalanced
注解即可:
// 以 RestTemplate 为例,在 bean 上面添加 @LoadBalanced 即可
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
如果使用了 feign 默认会执行负载均衡策略,feign 会在自动配置的时候加入负载均衡的功能,从而实现在调用时负载均衡。
二、 @LoadBalancerClients 与 @LoadBalancerClient
在某些情况下,你定义的负载均衡策略并不想作用于全局,那么可以使用这两个注解对特定的服务使用负载均衡策略。
@LoadBalancerClient
的作用是给特定的服务添加特定的负载均衡策;@LoadBalancerClients
的作用是将多个 @LoadBalancerClient
组合在一起使用,因为 @LoadBalancerClient
不能多个写在同一个地方
@LoadBalancerClients(
value = {
@LoadBalancerClient(value = "loadbalancer-provider", configuration = CustomRandomConfig.class),
@LoadBalancerClient(value = "loadbalancer-log", configuration = CustomRoundRobinConfig.class)
}, defaultConfiguration = LoadBalancerClientConfiguration.class
)
public class RestTemplateConfig {
}
上面代码的意思是,给 loadbalancer-provider
服务使用的负载均衡策略是 RandomLoadBalancer
随机负载均衡,给 loadbalancer-log
使用的是 RoundRobinLoadBalancer
轮训策略,其他没有标识的则使用默认的配置 LoadBalancerClientConfiguration
(轮询);
CustomRandomConfig
是自定义的配置,对应的是随机负载均衡的配置,CustomRoundRobinConfig
也是自定义的配置,为轮询负载均衡。
三、 自定义负载均衡
如果需要自定义策略,只需要实现 ReactiveLoadBalancer
接口并编写 choose(Request) 负载策略,可以参考已有的实现去做,例如默认的轮询 RoundRobinLoadBalancer
是怎么编写的
由于负载均衡在容器(父容器与子容器)中只有一个,因此如果你注册为 Bean 则会覆盖掉原先默认的轮训策略,因为默认的负载均衡加了 @ConditionalOnMissingBean 注解。
/**
* 自定义负载均衡 bean 配置
*
* @author zxb
* @date 2022-04-12 17:13
*/
@Configuration
// 表示全局使用同一个配置
@LoadBalancerClients(defaultConfiguration = {
SpringBeanConfiguration.class})
public class SpringBeanConfiguration {
@Bean
ReactorLoadBalancer<ServiceInstance> nacosTransferRuleLoadBalancer(Environment environment,