LoadBalancer
在微服务架构中,服务调用的时候,我们通常会使用负载均衡器来均衡各个服务的负载。Spring Cloud 为我们提供了负载均衡的功能,我们只需要在服务调用的地方加上 @LoadBalanced
注解即可。
之前我们使用过RestTemplate
来调用服务,并且加入了@LoadBalanced
注解。但是,就像之前所说的,@LoadBalanced
注解只是一个接口,需要一个实现类才能生效。
这个@LoadBalanced
属于 Spring Cloud Commons 组件,这个组件提供了一些接口,但是没有实现类。因此要看的文档是这篇。
Spring Cloud LoadBalancer
同样的,这个组件也有它的 Sprint Boot,因此要引入org.springframework.cloud:spring-cloud-starter-loadbalancer
。
然后我们可以使用LoadBalancerClient
来获取一个服务的实例,例如,
@Autowired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/payment/lb")
public String getPaymentLB() {
ServiceInstance serviceInstance = loadBalancerClient.choose("payment-service");
return serviceInstance.getUri().toString();
}
之前我们在RestTemplate
中使用@LoadBalanced
注解,就是在RestTemplate
访问前,先通过LoadBalancerClient
获取一个服务实例,然后再访问这个实例。
负载平衡算法
负载平衡其实有两种,一种是客户端负载均衡,一种是服务端负载均衡。
客户端负载平衡即是客户端自己去选择一个服务实例,然后访问这个实例。服务端负载均衡则是服务端的网关接受请求,然后再转发给一个服务实例。这里使用的就是客户端负载均衡,而服务端负载均衡可以用 Nginx 来实现。
默认使用的算法是轮询算法,即假设有 N 个服务实例,每次请求都会选择第 (N + 1) % N 个服务实例。
要切换算法,则要修改 ReactorLoadBalancer<ServiceInstance>
的配置,例如,
public class CustomLoadBalancerConfiguration {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory
.getLazyProvider(name, ServiceInstanceListSupplier.class),
name);
}
}
这样就切换到了随机算法。