还没有秃头吗?你真的需要大牛来教你如何深入解析Ribbon源码了
Ribbon源码解析
Ribbon 的 源 码 解 析 我 们 从 @LoadBalanced 开 始 讲 起 , 添 加@LoadBalanced注解后AsyncRestTemplate就具备了负载均衡的能力,代码如下:
在初始化HTTP客户端时会加载Ribbon的拦截代码,同时根据配置文件中设置的负载均衡策略或者代码实现定制好的负载均衡策略,实现HTTP请求过程中的后端服务分发。所以源码解读可以分为两个部分。
● 初始化构造过程:获取@LoadBalanced注解标记RestTemplate或者AsyncRestTemplate,然后添加拦截器。郑州心理疾病医院http://www.hyde8871.com/
● 负载均衡服务选择过程:在Ribbon设定的负载均衡策略下,从服务集群中根据预定的负载均衡策略实现后端服务的选取及请求转发。
如下图所示是一个简要的Ribbon初始化及调用拦截HTTP请求实现负载均衡的流程。
Ribbon的初始化过程
@LoadBalanced注解对RestTemplate做了标记,使用Ribbon的自动化配置加载类实现对负载均衡客户端的加载,在生成的RestTemplate的Bean上添加注解后,它会配置LoadBalancerClient。首先我们看一下LoadBalancerClient的源码实现:
说明:LoadBalancerClient是一个接口,里面有三个方法。
● ServiceInstance choose(String serviceId)方法,根据传入的serviceId(服务名),从负载均衡器中选择一个服务实例,服务实例通过ServiceInstance类来表示。
● execute方法,使用从负载均衡器中选择的服务实例来执行请求内容。
● URI reconstructURI ( ServiceInstance instance , URIoriginal ) 方 法 : 用 来 重 新 构 建 URI 。 我 们 通 过RestTemplate 请 求 后 端 服 务 时 会 使 用 serviceId ( 服 务名),这个方法会把请求的URI进行转换,返回host+port,再通过host+port的形式去请求服务。
从META-INF/spring.factories文件来看Ribbon的自动化加载机制,主要是Spring Common的LoadBalancerClient的初始化和加载过程:
Ribbon的自动配置实现
下面是Ribbon的自动化配置实现:
● 说 明 1 # : Ribbon 将 所 有 标 记 @LoadBalanced 注 解 的RestTemplate保存到一个List集合中。
● 说 明 2 # : Ribbon 借 助 了 Spring IoC 容 器 的SmartInitializingSingleton机制。实现该接口后,当所有单 例 Bean 都 被 初 始 化 完 成 后 , 容 器 会 调 用afterSingletonsInstantiated实现RestTemplateCustomizer的customize定制化方法。
● 说 明 3 # : 获 取 RestTemplate 的 interceptors , 在 构 造LoadBalancerInterceptor时需要传入LoadBalanceClient实例参数,LoadBalanceClient是一个接口,具体实现类将实现choose(服务实例选择)和execute(请求转发执行)方法,这一步完成Ribbon负载均衡策略Bean的构造。
● 说明4:将说明3#中构造的loadBalancerInterceptor Bean实例注入RestTemplate的定制化Bean中,这一步骤也会在说明2# 的 afterSingletonsInstantiated 方 法 中 被 调 用 , 完 成RestTemplate的定制化及与LoadBalancerInterceptor实例关联。