前言
注意本篇文章使用 SpringCloud2021.0.1
和 SpringBoot2.6.5
版本,使用Eureka
服务器进行服务注册与发现,主要讲述其负载均衡实现的流程和自定义负载均衡策略。
希望观众老爷们多多支持,并在评论区批评指正!
1. 负载均衡流程
1.1. 准备
我们用于发起请求调用的 restTemplate
对象(HTTP
客户端请求工具) 进行配置时,对其标注 @LoadBalanced
注解之后,会启用拦截器对我们发起的服务调用请求进行拦截。
通过 LoadBalancerInterceptor
拦截器进行拦截,实现自 ClientHttpRequestInterceptor
接口:
LoadBalancerInterceptor
拦截服务调用请求后,会获取 Uri
和 serviceName
作为 this.loadBalancer.execute()
的参数,然后执行 execute
方法。
我们点进去这个方法,会转到 LoadBalancerClient
接口,然后我们 Alt+Enter
进入该接口的实现:BlockingLoadBalancerClient
1.2. 具体流程
1.2.1. BlockingLoadBalancerClient 负载均衡的具体实现类
然后我们进行断点调试,查看一下具体的执行流程:假设发起请求 /borrow/1 获取用户1的借阅详细信息,那么会对 userservice
和 bookservice
发起服务调用。我们就看一下对 userservice
远程调用的执行过程吧。
我们点击步入,进入 BlockingLoadBalancerClient
的 execute(String serviceId, LoadBalancerRequest<T> request)
方法:
然后一直向下执行,到红色框位置:
通过创建对象LoadBalancerRequestAdapter
获取负载均衡请求适配器。
然后我们一直向下执行,到红色框位置:
supportedLifecycleProcessors
用于获取支持的生命周期处理器集合,我们没有加任何处理,返回的集合为空 size = 0
。
1.2.2. choose()
自动选择对应的微服务实例
然后通过调用 this.choose(serviceId, lbRequest)
通过服务名称和负载均衡适配器自动选择对应的服务实例信息。
我们点击步入这个方法:
然后通过 loadBalancerClientFactory
负载均衡客户端工厂的 getInstance
方法,获取 loadBalancer
负载均衡器,也就是负载均衡策略,默认为 RoundRobinLoadBalancer
(轮询分配策略,每个微服务实例依次获取请求),还有 RandomLoadBalancer
(随机分配策略,每个微服务实例随机获取请求)。
显然 loadBalancer
对象不为空,然后执行 Mono.from
方法根据「获取到的负载均衡分配策略」,获取一个 loadBalancerResponse
负载均衡的响应,也就是选择了 userservice
对应的一个微服务实例的相关信息,如端口,真实地址、服务状态等。这个过程是向Eureka
服务发起请求,Eureka
根据分配策略,选择一个可用的对应服务,然后会返回此服务的主机地址等信息:
然后进行返回结果给 serviceInstance
对象
如果serviceInstance
对象为空,则报错提示没有对应的微服务,服务调用失败。
1.2.3. 执行 excute
的重载方法
显然 serviceInstance
对象不为空,然后执行 excute
的重载方法。
先将 serviceInstance
对象封装为 defaultResponse
,再通过 serviceId
获取支持生命周期处理器。
然后进行判断 request
对象(负载均衡请求适配器)是不是一个Request
对象。如果是,就进行转型,否则就 new
一个新的 Request
对象。
然后遍历 supportedLifecycleProcessors
支持生命周期处理器,对请求进行一些处理。
下一步进入 try
语句块,获取 response
响应对象,返回給上一级。
返回的结果
1.2.4. 返回结果,执行真正的请求
返回到上一级之后,就执行真正的请求,然后返回结果
1.3. 总结
该过程就是通过拦截器拦截我们的服务调用请求,通过微服务名称,请求 Eureka
服务器获取服务的真实地址后,返回一个响应对象,包含该微服务的信息url
,然后根据这个信息向该微服务发起真正的请求。
2. 自定义负载均衡策略
LoadBalancer
默认提供了两种负载均衡策略:
-
RandomLoadBalancer
– 随机分配策略 -
「(默认)」 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
对象的配置类中:
value
指定使用该负载均衡策略的服务名称,configuration
指定该负载均衡策略的具体实现类。
2.2. 测试
-
在 BlockingLoadBalancerClient
中的choose
方法添加断点,观察是否采用我们指定的策略进行请求:
果然使用了我们指定的随机分配策略了。
-
我们采用一种直观的方式,看发给 userservice
的请求是否是随机的
我们发现 userservice01
被调用两次,userservice02
被调用四次,证明是随机的。而默认的轮询策略则是各三次。
原文始发于微信公众号(yanghi):SpringCloud微服务之LoadBalancer 负载均衡流程及自定义负载均衡策略
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/226621.html