如果只是想看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 以及自定义负载均衡算法的更多相关文章

  1. SpringCloud全家桶学习之客户端负载均衡及自定义负载均衡算法----Ribbon(三)

    一.Ribbon是什么? Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端  负载均衡的工具(这里区别于nginx的负载均衡).简单来说,Ribbon是Netf ...

  2. Ribbon,主要提供客户侧的软件负载均衡算法。

    Ribbon Ribbon,主要提供客户侧的软件负载均衡算法.Ribbon客户端组件提供一系列完善的配置选项,比如连接超时.重试.重试算法等.Ribbon内置可插拔.可定制的负载均衡组件.下面是用到的 ...

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

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

  4. [Abp vNext 源码分析] - 11. 用户的自定义参数与配置

    一.简要说明 文章信息: 基于的 ABP vNext 版本:1.0.0 创作日期:2019 年 10 月 23 日晚 更新日期:暂无 ABP vNext 针对用户可编辑的配置,提供了单独的 Volo. ...

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

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

  6. springmvc 源码分析(三) -- 自定义处理器映射器和自定义处理器适配器,以及自定义参数解析器 和错误跳转自定页面

    测试环境搭建: 本次搭建是基于springboot来实现的,代码在码云的链接:https://gitee.com/yangxioahui/thymeleaf.git DispatcherServlet ...

  7. ribbon源码分析

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

  8. Dubbo学习源码总结系列五--集群负载均衡

            Dubbo提供了哪些负载均衡机制?如何实现的?          LoadBalance接口:可以看出,通过SPI机制默认为RandomLoadBalance,生成的适配器类执行sel ...

  9. 读书笔记-Ribbon源码分析

    @LoadBalanced注解用来给RestTemplate做标记,以使用负载均衡的客户端来配置. 通过搜索LoadBalancerClient可以发现,LoadBalancerClient是Spri ...

随机推荐

  1. 模拟退火详解&P1433题解

    前排提示:LZ是个菜比,有可能有讲的不对的地方,请在评论区指出qwq 0.基本思想 模拟退火其实没有那么高大上.说白了就是初始化一个"温度".每次随机乱选一个方案,如果比以前的方案 ...

  2. JAVA开源软件的技术选型--开源软件诞生2

    技术准备--第2篇 用日志记录“开源软件”的诞生 赤龙ERP开源地址,点亮星标,支持一下,万分感谢 码云:https://gitee.com/redragon/redragon-erp github: ...

  3. webpack 打包的具体步骤

    webpack打包的方法: 方法一 创建一个src文件夹(存放自己的代码),dist文件夹(打包到此文件夹) 2编写自己的代码,在src文件夹中创建一个主模块main.js和若干个js文件,将模块js ...

  4. 硬盘网盘U盘全部可以丢掉了,这个设备可以让你享受随身带着几个T的感受

    前言 有小伙伴问我,你怎么老写技术类文章,能不能写点别的. 其实我兴趣挺广泛的,早年还有机会做个游戏博主,可惜最近2年金盆洗手了.戒了手游,ns和ps4都在吃灰.能完整玩完的游戏屈指可数.但是对于折腾 ...

  5. Collection/Map关系图

  6. 在一台电脑上,添加多个Git的ssh key

    Git的第一套公秘钥默认名为 id_rsa ,如果你想要生成另外一个公钥,比如 aysee ,你也可以使用任何你喜欢的名字. 步骤如下:(总共四大操作) 一.生成ssh key 1.生成一个新的自定义 ...

  7. ASP调用WEBSERVICE并对返回结果进行解析时遇到的问题

    项目上用动易平台做新闻发布网站,动易平台是用ASP做的,期间需要根据当前登录的用户,取其他系统比如OA的待办事项进行列表展示,OA组的同事给了我一个WSDL接口,百度了很多ASP调用webservic ...

  8. Activiti7 任务人员动态分配(理论)

    之前一直用的流程模型都是,固态的,写死的 由于固定分配方式,任务只能一步一步执行,执行到每一个任务将按照bpmn的配置去分配任务负责人.这显然在实际开发中是不可能的 所以我们需要动态分配人员 表达式分 ...

  9. JVM学习第三天(JVM的执行子系统)之类加载机制

    好几天没有学习了,前几天因为导出的事情,一直在忙,今天继续学习, 其实今天我也遇到了一个问题,如果有会的兄弟可以评论留给我谢谢; 问题:fastJSON中JSONObject.parseObject做 ...

  10. webservice的某些配置

    ajax调用的时候配置 <system.webServer> <validation validateIntegratedModeConfiguration="false& ...