主要说一下springcloud alibaba 在使用nacos注册中心过程中,请求服务负载均衡的配置方法
引入依赖包 这个依赖包是springcloud在新版本的负载均衡实现,2020版本以上
`
java
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>XXX</version>
</dependency>`
默认情况下,负载均衡不需要配置,默认轮询策略,如果我们想改,怎么做呢
先说一下springcloud LoadBalance原理及结构
1、负载均衡器的管理
ReactorLoadBalancer<ServiceInstance>
这就是一个服务绑定的负载均衡器,为每一个服务创建一个负载均衡实体类,实现服务的隔离,虽然我也不知道为啥要这样做
2、工厂来管理负载均衡器
java
LoadBalancerClientFactory
这个工厂相当于管理所有的负载均衡器,你可以通过getInstance
方法拿到你的服务名绑定的负载均衡器
3、负载均衡器
java
ReactorServiceInstanceLoadBalancer
每一个负载均衡器都实现了这个接口 ,内部定义了choose方法,外部就可以用他的choose方法来找到一个服务
类结构讲完了 怎么自定义一个新的负载均衡器呢
这里就需要一个配置类
java
@Configuration
public class FeignForceLoadBalancerConfig {
@Bean
public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String serviceId = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
System.out.println("Init RandomLoadBalancer for service: " + serviceId);
return new RandomLoadBalancer(
loadBalancerClientFactory.getLazyProvider(serviceId, ServiceInstanceListSupplier.class),
serviceId);
}
这里就注册了一个随机策略的负载均衡器,这也是springcloud实现了的,自己定义的话可能需要自己实现接口了
怎么用呢?
上面说了负载均衡器和服务绑定在一起的,所以说还是得声明一下绑定关系
1、随便找个配置类, 加个注解,就说明这个服务走这个负载均衡器
java
@LoadBalancerClient(value="service-product",configuration = FeignForceLoadBalancerConfig.class)
不知道为啥他要这么设计,反正挺恶心, 一个负载均衡器和服务绑定,多个负载均衡器就得写多个配置类
这个时候你再在客户端请求service-product服务,那就会走loadbalance,不论你是通过RestTemplate请求还是通过LoadBalanceClient请求服务
附上一个调用链图
┌────────────────────────────┐
│ @LoadBalancerClient │
│ name="service-product" │
│ config = CustomLBConfig │
└────────────┬───────────────┘
│
┌───────────────────────────▼──────────────────────────┐
│ Spring Context 注入 Bean: │
│ ReactorLoadBalancer<ServiceInstance> │
│ → 例如 RandomLoadBalancer │
│ → 由 CustomLBConfig 中的 @Bean 方法提供 │
└───────────────────────────┬──────────────────────────┘
│
┌──────────────────▼───────────────────┐
│ LoadBalancerClientFactory │
│ - 管理每个服务对应的负载类实例 │
│ - 按 serviceId 提供策略 │
└──────────────────┬───────────────────┘
│
┌──────────────────────────▼──────────────────────────┐
│ ReactorServiceInstanceLoadBalancer.choose(request) │
│ (通用选择接口,最终调用你配置的策略类) │
└──────────────────────────┬──────────────────────────┘
│
┌────────────────────────────────▼────────────────────────────────┐
│ │
│ Feign 调用链: │
│ FeignClient → LoadBalancerFeignClient → choose() │
│ │
│ RestTemplate 调用链: │
│ RestTemplate + @LoadBalanced → LoadBalancerInterceptor → │
│ choose() │
│ │
└────────────────────────────────────────────────────────────────┘