SpringCloud LoadBalancer介绍
Spring Cloud LoadBalancer是一个客户端负载均衡器,类似于Ribbon,但是由于Ribbon已经进入维护模式,所以Spring Cloud全家桶在Spring Cloud Commons项目中,添加了Spring cloud Loadbalancer作为新的负载均衡器。
客户端负载均衡
Loadbalancer与Ribbon都是客户端负载均衡,说白就是在客户端获取能够调用的服务列表,通过随机、轮询、权重配置、ip、健康检测等负载策略,选择要调用的服务实例。
相对而言服务端的负载均衡就是客户端发起调用后,服务器端比如Nginx组件在维护的服务列表中通过负载均衡选择一个响应请求的服务实例。同样Nginx也可以在upstream中配置随机、轮询等负载均衡策略。
LoadBalancer源码浅析
LoadBalancer默认支持随机RandomLoadBalancer
跟轮询RoundRobinLoadBalancer
两种负载均衡策略。RandomLoadBalancer
的choose
方法就是从客户端获取的服务列表中随机选择一个服务。
服务列表由ServiceInstanceListSupplier
的实现类提供,这里我们微服务调用通过DiscoveryClientServiceInstanceListSupplier
代理类从注册中心上面获取ServiceInstanceList
,Nacos的底层实现类是NacosReactiveDiscoveryClient
。
public class RandomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private static final Log log = LogFactory.getLog(RandomLoadBalancer.class);
private final String serviceId;
private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;
/**
* @param serviceInstanceListSupplierProvider a provider of
* {@link ServiceInstanceListSupplier} that will be used to get available instances
* @param serviceId id of the service for which to choose an instance
*/
public RandomLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider,
String serviceId) {
this.serviceId = serviceId;
this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
}
@SuppressWarnings("rawtypes")
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider
.getIfAvailable(NoopServiceInstanceListSupplier::new);
return supplier.get(request).next()
.map(serviceInstances -> processInstanceResponse(supplier, serviceInstances));
}
private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier,
List<ServiceInstance> serviceInstances) {
Response<ServiceInstance> serviceInstanceResponse = getInstanceResponse(serviceInstances);
if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {
((SelectedInstanceCallback) supplier).selectedServiceInstance(serviceInstanceResponse.getServer());
}
return serviceInstanceResponse;
}
private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
if (instances.isEmpty()) {
if (log.isWarnEnabled()) {
log.warn("No servers available for service: " + serviceId);
}
return new EmptyResponse();
}
int index = ThreadLocalRandom.current().nextInt(instances.size());
ServiceInstance instance = instances.get(index);
return new DefaultResponse(instance);
}
}
版权声明:
本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自
编程之家!
喜欢就支持一下吧