@LoadBalanced注解用来给RestTemplate做标记,以使用负载均衡的客户端来配置。

通过搜索LoadBalancerClient可以发现,LoadBalancerClient是SpringCloud定义的一个接口

public interface LoadBalancerClient {
Serviceinstance choose(String serviceId);
<T> T execute(String serviceid, LoadBalancerRequest<T> request) throws
IOException;
URI reconstructURI(Serviceinstance instance, URI original);

}

通过该接口,了解客户端负载均衡器因该具备几种能力。

1.choose(String serviceId):根据传入的服务名serviceId,从负载均衡器中挑选一个对应的服务实例。

2.<T> T execute(String serviceid, LoadBalancerRequest<T> request):使用从负载均衡器中挑选服务实例来执行请求内容。

3.URI reconstructURI(Serviceinstance instance, URI original);:为系统构建一个合适的host:port形式的URI。在分布式系统中,我们使用逻辑上的服务名作为host来构建URI进行请求 。

LoadBalancerAutoConfiguration 类为实现客户端负载均衡的自动化配置类。通过查看配置类的源码。可以知道Ribbon实现的负载均衡自动化配置需要满足下面两个条件。

1.RestTemplate类必须存在于当前工程的环境中。

2.在Spring的Bean工程中必须有LoadBalancerClient的实现的Bean。

在改自动化配置类中,主要做了下面三个事:

1.创建了一个LoadBalancerInterceptor的Bean,用于实现客户端发起请求进行拦截,以实现客户端的负载均衡。

2.创建一个RestTemplateCustomizer的Bean,用于给RestTemplate增加LoadBalancerInterceptor拦截器。

3.维护了一个被@LoadBalanced注释修饰的RestTemplate对象列表。并在这里进行初始化,通过调用RestTemplateCustomizer的实例来给需要客户端负载均衡的RestTemplate增加LoadBalancerInterceptor拦截器。

通过源码分析,拦截器注入了LoadBalancerClient的实现,当一个被@LoadBalanced注解修饰的RestTemplate对象想外发起HTTP请求时,会被LoadBalancerInterceptor类的intercept函数所拦截。由于我们在使用RestTemplate时采用了服务名作为host,所以直接从HttpRequest的URI对象中通过getHost()就可以拿到服务名。然后调用execute函数去根据服务名来选择实例并发起实际的请求。

以上的LoadBalancerClient还只是一个抽象的负载均衡器接口,所以我们还需要找到他的具体实现类来进一步进行分析。他的具体实现类是RibbonLoadBalancerClient。

在RibbonLoadBalancerClient的execute函数实现中,第一步就是通过getServer根据传入的服务名serviceId去获得具体的服务实例。

SpringCloud默认财通了ZoneAwareLoadBalancer来实现负载均衡器。

通过ZoneAwareLoadBalancer的chooseServer函数获取了负载均衡策略分配到的服务实例对象Server之后,还将起对象包装成RibbonServer对象(该对象处理存储了服务实例的对象之外,还增加了服务名serviceId,是否需要使用HTTPS等其他信息),然后使用该对象在回调LoadBalancerInterceptor请求拦截器中LoadBalancerRequest的apply函数,向一个世纪的具体服务实例发起请求,从而实现一开始以服务名为host的URI请求到host:post形式的实际访问地址的转换。

在apply函数中传入的ServiceInstance接口对象是对服务实例的抽象定义,在改接口暴露了服务治理系统中每个服务实例需要提供的一些基本信息。比如serviceId,host,post等,具体定义如下。

public interface ServiceInstance {
String getServiceId(); String getHost(); int getPort(); boolean isSecure(); URI getUri(); Map<String, String> getMetadata();
}

  上面提到的具体包装Server服务实例的RibbonServer对象就是ServiceInstance接口的实现,可以看到他除了包装Server对象之外,还存储了服务名,是否使用HTTPS标识以及一个Map类型的元数据集合。

从apply的实现中,可以看到他具体执行的时候,还传入了ServiceRequestWrapper对象,该对象继承了HttpRequestWrapper并重写了getURI函数,重写后的getURI通过调用LoadBalancerClient接口的reconstructURI函数来重新构建一个URI来进行访问。

读书笔记-Ribbon源码分析的更多相关文章

  1. Nginx学习笔记4 源码分析

    Nginx学习笔记(四) 源码分析 源码分析 在茫茫的源码中,看到了几个好像挺熟悉的名字(socket/UDP/shmem).那就来看看这个文件吧!从简单的开始~~~ src/os/unix/Ngx_ ...

  2. Ribbon源码分析(二)-- 服务列表的获取和负载均衡算法分析

    上一篇博客(https://www.cnblogs.com/yangxiaohui227/p/12614343.html)分享了ribbon如何实现对http://product/info/这个链接重 ...

  3. Ribbon源码分析(一)-- RestTemplate 以及自定义负载均衡算法

    如果只是想看ribbon的自定义负载均衡配置,请查看: https://www.cnblogs.com/yangxiaohui227/p/13186004.html 注意: 1.RestTemplat ...

  4. Spring Cloud Ribbon 源码分析---负载均衡算法

    上一篇分析了Ribbon如何发送出去一个自带负载均衡效果的HTTP请求,本节就重点分析各个算法都是如何实现. 负载均衡整体是从IRule进去的: public interface IRule{ /* ...

  5. ribbon源码分析

    对于ribbon的使用我们只需要在RestTemplate的申明上面加上 @LoadBalanced 注解之后那么这个RestTemplate就具有了负载均衡的功能 ribbon是怎么实现这一功能的? ...

  6. 【黑客免杀攻防】读书笔记15 - 源码免杀、C++壳的编写

    1.源码免杀 1.1 定位产生特征的源码 定位文件特征 1.根据MyCCL的特征码定位工具,定位出有特征的地址 2.根据VS的反汇编窗口,输入有特征的地址得到特征地址与源码的关系 3.插入Messag ...

  7. Spring Cloud Ribbon源码分析---负载均衡实现

    上一篇结合 Eureka 和 Ribbon 搭建了服务注册中心,利用Ribbon实现了可配置负载均衡的服务调用.这一篇我们来分析Ribbon实现负载均衡的过程. 从 @LoadBalanced入手 还 ...

  8. ActiveMQ笔记:源码分析

    本文对ActiveMQ的启动过程,以及BrokerService,TransportConnector和NetworkConnector等几个重要的模块的代码做一个简要的分析. 启动过程 如果要快速地 ...

  9. odoo开发笔记--定时任务源码分析

    场景描述: 处理思路: 参考文章: 定时任务相关: https://www.jianshu.com/p/ad48239f84d6 https://blog.csdn.net/M0relia/artic ...

随机推荐

  1. VK Cup 2018 - Round 1+Codeforces Round #470

    A. Primal Sport 题意:有两个人轮流玩游戏.给出数X(i-1),轮到的人需要找到一个小于X(i-1)的素数x,然后得到Xi,Xi是x的倍数中大于等于X(i-1)的最小的数.现在已知X2, ...

  2. selenium的下拉选择框

    今天总结下selenium的下拉选择框.我们通常会遇到两种下拉框,一种使用的是html的标签select,另一种是使用input标签做的假下拉框. 后者我们通常的处理方式与其他的元素类似,点击或使用J ...

  3. 75. Sort Colors(荷兰国旗问题 三指针)

      Given an array with n objects colored red, white or blue, sort them so that objects of the same co ...

  4. spring boot Rabbitmq集成,延时消息队列实现

    本篇主要记录Spring boot 集成Rabbitmq,分为两部分, 第一部分为创建普通消息队列, 第二部分为延时消息队列实现: spring boot提供对mq消息队列支持amqp相关包,引入即可 ...

  5. Java并发之Semaphore的使用

    Java并发之Semaphore的使用 一.简介 今天突然发现,看着自己喜欢的球队发挥如此的棒,然后写着博客,这种感觉很爽.现在是半场时间,就趁着这个时间的空隙,说说Java并发包中另外一个重量级的类 ...

  6. SQL TOP分页法

    原理: PageSize, PageIndex: 升序   order  by  a asc a的 值 大于, 上一页数据 最大的  a值. 降序  order by  a desc a的 值 小于, ...

  7. pt-osc原理

    pt-osc原理 1.检查设置环境 测试db是否可连通,并且验证database是否存在 SET SESSION innodb_lock_wait_timeout=1 //InnoDB事务等待行锁的超 ...

  8. 深入解析Koa之核心原理

    这篇文章主要介绍了玩转Koa之核心原理分析,本文从封装创建应用程序函数.扩展res和req.中间件实现原理.异常处理的等这几个方面来介绍,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参 ...

  9. tesseract编译各种 “锟斤拷” 等中文乱码 编译失败问题

    编译tesseract - ocr时 各种不通过 也很疑惑,完全按照官方指导来的啊 首先以为是vs的编码问题,随切换选项-切换Unicode或多编码字符集,但仍无效. 定位到乱码的文件,用notepa ...

  10. python_初步

    官网地址:http://www.python.org/ Python最新源码,二进制文档,新闻资讯 Python文档下载地址:www.python.org/doc/ python教程:http://w ...