Ribbon源码分析(一)-- RestTemplate 以及自定义负载均衡算法
如果只是想看ribbon的自定义负载均衡配置,请查看: https://www.cnblogs.com/yangxiaohui227/p/13186004.html
注意:
1.RestTemplate 所在jar为:org.springframework.web.client.RestTemplate 说明了其并不依赖springcloud
2. 所以2个springboot项目其实是可以调用的,而并不需要依赖springCloud,如图:
product服务:
order服务:
浏览器访问order服务:
由此可见,服务间调用并不需要依赖springcloud组件,那么,这样调用会存在什么问题呢?
1.ip和端口需要我们在每个调用的接口都要写死
2.如果一个服务做了集群,这样也是只能调用写死的那个服务
解决方案:引入springCloud
改造下:product创建2个实例,架构图如下:
product1的配置:
product2的配置:
order服务自定义轮询算法调用product服务:
调用第一次:
调用第二次:
由此可以见,负载均衡策略已经实现
然而:我们还是要拼接ip和端口,如果我们想通过服务名(spring.application.name)去调用呢:
调用结果跟之前的是一致的,默认使用轮询负载均衡算法; 上面的例子虽然@LoadBalanced不是ribbon的依赖包,但请求过程中最后还是会依赖ribbon进行负载均衡
思考:上面的例子为何能通过http://product/get去访问,我们知道要访问一个服务必须知道Ip和端口,最终要变成http://ip地址:端口/get形式的url
猜想:
1. http://product/get 请求会被拦截
2. 通过http://product/get可以获取到服务名称为product
3. 通过服务名称product 可以获取服务列表
4. 通过服务列表,按照一定的算法获取一个服务,本质就是从一个list集合中获取一个服务,关键就是如何确定下标index
5. 通过服务拿到对应的IP和端口,然后重新构建url
一.解决第一个猜想:http://product/get被拦截,拦截器在哪里,又是什么时候跟restTemplate 扯上关系的
1.1 springboot自动装配机制的理解
1.2 根据springboot自动装配机制,我们找下spring-cloud-netflix-ribbon的源码,可以看到
查看内容:
由此可见,该类会被springboot自动装配,后续的源码分析都会围绕该类来走
1.3分析LoadBalancerAutoConfiguration该类
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RestTemplate.class)
@ConditionalOnBean(LoadBalancerClient.class)
@EnableConfigurationProperties(LoadBalancerRetryProperties.class)
public class LoadBalancerAutoConfiguration { @LoadBalanced
@Autowired(required = false)
private List<RestTemplate> restTemplates = Collections.emptyList(); //只有加了@LoadBalanced注解的RestTemplate就会加到该集合中 @Autowired(required = false)
private List<LoadBalancerRequestTransformer> transformers = Collections.emptyList(); @Bean
public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(
final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) {
return () -> restTemplateCustomizers.ifAvailable(customizers -> {
for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
for (RestTemplateCustomizer customizer : customizers) {
customizer.customize(restTemplate); //遍历restTemplates,给其添加自定义信息
}
}
});
} @Bean
@ConditionalOnMissingBean
public LoadBalancerRequestFactory loadBalancerRequestFactory(
LoadBalancerClient loadBalancerClient) {
return new LoadBalancerRequestFactory(loadBalancerClient, this.transformers);
} @Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
static class LoadBalancerInterceptorConfig { @Bean
public LoadBalancerInterceptor ribbonInterceptor(
LoadBalancerClient loadBalancerClient,
LoadBalancerRequestFactory requestFactory) {
return new LoadBalancerInterceptor(loadBalancerClient, requestFactory); //这个就是我们要找的拦截器了
} @Bean
@ConditionalOnMissingBean
public RestTemplateCustomizer restTemplateCustomizer(
final LoadBalancerInterceptor loadBalancerInterceptor) {
return restTemplate -> {
List<ClientHttpRequestInterceptor> list = new ArrayList<>(
restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list); //拦截器在这个里设置到restTempalte中的
};
} } //省略部分代码 }
下面我们看看RestTemplate类的继承结构
1.4 小结: springboot自动装配机制会对META-INF\spring.factories中key为EnableAutoConfiguration的类进行初始化,而ribbon和springcloud集成的文件中含有的类为:
org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration,该类初始化时会先初始化LoadBalancerAutoConfiguration,而LoadBalancerAutoConfiguration这个类是一个配置类,里面含有的@Bean注解的方法返回的类都会
被初始化和注入spring容器,该类会为含有@LoadBalanced注解的RestTemplate类添加拦截器,而拦截器最终会存到父类的一个集合中
之后流程debug调试:
二.解决猜想通过 http://product/get可以获取到服务名称为product
//此处省略部分过程
猜想三和猜想四解决: 通过服务名称product 可以获取服务列表,并通过服务列表取出一个服务
//获取服务列表和和从服务列表中取出一个服务,下一篇博客将会做详细的讲解
猜想五:通过获取的服务进行url重构:
继续调试:
//省略部分调用
至此可以发现,ribbon底层主要是将我们的服务名称替换为ip和端口
附加:RestTemplate的底层调用:
响应结果是如何转换成String的呢?
继续跟进
Ribbon源码分析(一)-- RestTemplate 以及自定义负载均衡算法的更多相关文章
- SpringCloud全家桶学习之客户端负载均衡及自定义负载均衡算法----Ribbon(三)
一.Ribbon是什么? Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具(这里区别于nginx的负载均衡).简单来说,Ribbon是Netf ...
- Ribbon,主要提供客户侧的软件负载均衡算法。
Ribbon Ribbon,主要提供客户侧的软件负载均衡算法.Ribbon客户端组件提供一系列完善的配置选项,比如连接超时.重试.重试算法等.Ribbon内置可插拔.可定制的负载均衡组件.下面是用到的 ...
- Ribbon源码分析(二)-- 服务列表的获取和负载均衡算法分析
上一篇博客(https://www.cnblogs.com/yangxiaohui227/p/12614343.html)分享了ribbon如何实现对http://product/info/这个链接重 ...
- [Abp vNext 源码分析] - 11. 用户的自定义参数与配置
一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 23 日晚 更新日期:暂无 ABP vNext 针对用户可编辑的配置,提供了单独的 Volo. ...
- Spring Cloud Ribbon源码分析---负载均衡实现
上一篇结合 Eureka 和 Ribbon 搭建了服务注册中心,利用Ribbon实现了可配置负载均衡的服务调用.这一篇我们来分析Ribbon实现负载均衡的过程. 从 @LoadBalanced入手 还 ...
- springmvc 源码分析(三) -- 自定义处理器映射器和自定义处理器适配器,以及自定义参数解析器 和错误跳转自定页面
测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git DispatcherServlet ...
- ribbon源码分析
对于ribbon的使用我们只需要在RestTemplate的申明上面加上 @LoadBalanced 注解之后那么这个RestTemplate就具有了负载均衡的功能 ribbon是怎么实现这一功能的? ...
- Dubbo学习源码总结系列五--集群负载均衡
Dubbo提供了哪些负载均衡机制?如何实现的? LoadBalance接口:可以看出,通过SPI机制默认为RandomLoadBalance,生成的适配器类执行sel ...
- 读书笔记-Ribbon源码分析
@LoadBalanced注解用来给RestTemplate做标记,以使用负载均衡的客户端来配置. 通过搜索LoadBalancerClient可以发现,LoadBalancerClient是Spri ...
随机推荐
- 【干货!!】三句话搞懂 Redis 缓存穿透、击穿、雪崩
前言 如何有效的理解并且区分 Reids 穿透.击穿和雪崩之间的区别,一直以来都挺困扰我的.特别是穿透和击穿,过一段时间就稀里糊涂的分不清了. 为了有效的帮助笔者自己,以及拥有同样烦恼的朋友们区分这三 ...
- npm修改默认配置
1.nodejs在program files下面会造成一些项目中的问题,因此nodejs在program files下需要先卸载nodejs 2.安装nodejs到自定义的目录下面,例:D:\node ...
- GPU虚拟机创建时间深度优化
桔妹导读:GPU虚拟机实例创建速度慢是公有云面临的普遍问题,由于通常情况下创建虚拟机属于低频操作而未引起业界的重视,实际生产中还是存在对GPU实例创建时间有苛刻要求的业务场景.本文将介绍滴滴云在解决 ...
- 焦大:做SEO应该研究的用户需求的方向
http://www.wocaoseo.com/thread-60-1-1.html 最近收到打击很大,收获也颇多,这一切都莫过于用户需求的问题.我曾经给我弟说过,我对检索排名特征识别.提取和计算自认 ...
- Java自学-图形界面 Swing中的线程
Swing中的线程 步骤 1 : 三种线程 在Swing程序的开发中,需要建立3种线程的概念 初始化线程 初始化线程用于创建各种容器,组件并显示他们,一旦创建并显示,初始化线程的任务就结束了. 事件调 ...
- python os库的使用方法 + 自动化安装第三方库脚本
一.os库基本介绍 os库提供通用的.基本的操作系统交互功能,包括windows.Mac os.linux os库是python标准库,包含几百个函数 常用路径操作.进程管理.环境参数等几类 路径操作 ...
- JVM 垃圾收集算法 标记-清楚、标记-复制、标记-整理
摘要 Java程序在运行过程中会产生大量的对象,但是内存大小是有限的,如果光用而不释放,那内存迟早被耗尽.如C.C++程序,需要程序员手动释放内存,Java则不需要,是由垃圾回收器去自动回收. 垃圾回 ...
- 【Android】SwipeRefreshLayout的简单使用教程。下拉刷新控件炫酷效果。
作者:程序员小冰,GitHub主页:https://github.com/QQ986945193 新浪微博:http://weibo.com/mcxiaobing 首先给大家看一下我们今天这个最终实现 ...
- 《神经网络的梯度推导与代码验证》之CNN的前向传播和反向梯度推导
在FNN(DNN)的前向传播,反向梯度推导以及代码验证中,我们不仅总结了FNN(DNN)这种神经网络结构的前向传播和反向梯度求导公式,还通过tensorflow的自动求微分工具验证了其准确性.在本篇章 ...
- Codeforces Round #580 (Div. 2)-D. Shortest Cycle(思维建图+dfs找最小环)
You are given nn integer numbers a1,a2,…,ana1,a2,…,an. Consider graph on nn nodes, in which nodes ii ...