Skip to main content

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);
}
}

这样就切换到了随机算法。