SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

前言

注意本篇文章使用 SpringCloud2021.0.1SpringBoot2.6.5 版本,使用Eureka服务器进行服务注册与发现,主要讲述其负载均衡实现的流程和自定义负载均衡策略。

希望观众老爷们多多支持,并在评论区批评指正!

1. 负载均衡流程

1.1. 准备

我们用于发起请求调用的 restTemplate 对象(HTTP客户端请求工具) 进行配置时,对其标注 @LoadBalanced注解之后,会启用拦截器对我们发起的服务调用请求进行拦截。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

通过 LoadBalancerInterceptor拦截器进行拦截,实现自 ClientHttpRequestInterceptor 接口:

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

LoadBalancerInterceptor拦截服务调用请求后,会获取 UriserviceName 作为 this.loadBalancer.execute() 的参数,然后执行 execute方法。

我们点进去这个方法,会转到 LoadBalancerClient接口,然后我们 Alt+Enter 进入该接口的实现:BlockingLoadBalancerClient

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

1.2. 具体流程

1.2.1. BlockingLoadBalancerClient 负载均衡的具体实现类

然后我们进行断点调试,查看一下具体的执行流程:假设发起请求 /borrow/1 获取用户1的借阅详细信息,那么会对 userservicebookservice 发起服务调用。我们就看一下对 userservice 远程调用的执行过程吧。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略
SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略
SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

我们点击步入,进入 BlockingLoadBalancerClientexecute(String serviceId, LoadBalancerRequest<T> request)方法:

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

然后一直向下执行,到红色框位置:

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

通过创建对象LoadBalancerRequestAdapter获取负载均衡请求适配器。

然后我们一直向下执行,到红色框位置:
SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

supportedLifecycleProcessors 用于获取支持的生命周期处理器集合,我们没有加任何处理,返回的集合为空 size = 0

1.2.2. choose() 自动选择对应的微服务实例

然后通过调用 this.choose(serviceId, lbRequest) 通过服务名称和负载均衡适配器自动选择对应的服务实例信息。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

我们点击步入这个方法:

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

然后通过 loadBalancerClientFactory 负载均衡客户端工厂的 getInstance 方法,获取 loadBalancer 负载均衡器,也就是负载均衡策略,默认为 RoundRobinLoadBalancer(轮询分配策略,每个微服务实例依次获取请求),还有 RandomLoadBalancer(随机分配策略,每个微服务实例随机获取请求)。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略
SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

显然 loadBalancer 对象不为空,然后执行 Mono.from方法根据「获取到的负载均衡分配策略」,获取一个 loadBalancerResponse 负载均衡的响应,也就是选择了 userservice对应的一个微服务实例的相关信息,如端口,真实地址、服务状态等。这个过程是向Eureka服务发起请求,Eureka根据分配策略,选择一个可用的对应服务,然后会返回此服务的主机地址等信息:

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

然后进行返回结果给 serviceInstance 对象
SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

如果serviceInstance 对象为空,则报错提示没有对应的微服务,服务调用失败。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

1.2.3. 执行 excute 的重载方法

显然 serviceInstance 对象不为空,然后执行 excute的重载方法。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

先将 serviceInstance对象封装为 defaultResponse,再通过 serviceId获取支持生命周期处理器。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

然后进行判断 request 对象(负载均衡请求适配器)是不是一个Request 对象。如果是,就进行转型,否则就 new 一个新的 Request 对象。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

然后遍历 supportedLifecycleProcessors 支持生命周期处理器,对请求进行一些处理。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

下一步进入 try 语句块,获取 response 响应对象,返回給上一级。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

返回的结果

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

1.2.4. 返回结果,执行真正的请求

返回到上一级之后,就执行真正的请求,然后返回结果

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略
SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

1.3. 总结

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

该过程就是通过拦截器拦截我们的服务调用请求,通过微服务名称,请求 Eureka服务器获取服务的真实地址后,返回一个响应对象,包含该微服务的信息url,然后根据这个信息向该微服务发起真正的请求。

2. 自定义负载均衡策略

LoadBalancer默认提供了两种负载均衡策略:

  1. RandomLoadBalancer  –  随机分配策略
  2. 「(默认)」 RoundRobinLoadBalancer  –  轮询分配策略,请求会依次分配给每个微服务实例

2.1. 自定义负载均衡策略

现在我们希望修改默认的负载均衡策略,比如我们现在希望用户服务采用随机分配策略,我们需要先创建随机分配策略的配置类(不用加@Configuration):

public class LoadBalancerConfig {

//将官方提供的 RandomLoadBalancer 注册为Bean
@Bean
public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory){
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}

}

然后我们需要为对应的服务指定负载均衡策略,配置在 template 对象的配置类中:

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

value 指定使用该负载均衡策略的服务名称,configuration 指定该负载均衡策略的具体实现类。

2.2. 测试

  1. BlockingLoadBalancerClient 中的 choose 方法添加断点,观察是否采用我们指定的策略进行请求:
SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

果然使用了我们指定的随机分配策略了。

SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略
  1. 我们采用一种直观的方式,看发给 userservice 的请求是否是随机的
SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

我们发现 userservice01 被调用两次,userservice02 被调用四次,证明是随机的。而默认的轮询策略则是各三次。

原文始发于微信公众号(yanghi):SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/226621.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!