RestTemplate基于Ribbon负载均衡实现原理 上

都知道 RestTemplate 是基于 Ribbon实现的负载均衡,那么Ribbon又是如何做到的 ?

首先找到 spring-cloud-netflix-ribbon-2.1.0.RELEASE.jar 这个jar包

1.自动配置创建RibbonAutoConfiguration

image-20220510203440880

查看META-INF下的spring.factories文件

image-20220510203522438

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration

利用了SpringBoot自动配置机制,往容器中添加了一个自动配置类 RibbonAutoConfiguration

2. 加载 LoadBalancerAutoConfiguration

`RibbonAutoConfiguration 位于 org.springframework.cloud.netflix.ribbon 包下

image-20220510203733312

注意这个@AutoConfigureAfter注解 在当前类加载完成后,将加载 LoadBalancerAutoConfiguration 自动配置类

image-20220510204136983

跟进 LoadBalancerAutoConfiguration 自动配置类

3.找到需要定制的RestTemplate对象

来到 org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration

image-20220510204928657

首先能看到一个成员属性 restTemplates 类型是List 也就是 RestTemplate 的集合

头上标了一个 @Autowired 和一个 @LoadBalanced 注解 很迷惑对吧 什么时候 @Autowired 能和 @LoadBalanced 搭配使用了 ?

点进 @LoadBalanced 注解 可以看到有一个 @Qualifier 注解 恍然大悟了吧 原来这一步是在注入容器中 所有标记了 @LoadBalanced注解的 RestTempalte 对象

image-20220510205109223

4.定制 RestTemplate 添加拦截器

往下 来到 静态内部类的LoadBalancerInterceptorConfig的ribbonInterceptor方法 可以看到往容器中添加了一个 LoadBalancerInterceptor 对象

image-20220510210021591

继续往下看 来到 restTemplateCustomizer 方法

image-20220510205526174

返回值是一个函数式接口

image-20220510211239136

这里相当于往容器中存了一个lombad表达式(匿名实现类) 注意此时并未执行

然后我们回到上面的代码

找到 loadBalancedRestTemplateInitializerDeprecated 方法 打个断点

image-20220510210732115

` LoadBalancerAutoConfiguration.this.restTemplates 也就是上面自动注入的所有标注了@LoadBalanced 注解的RestTemplate对象集合

进行遍历 然后遍历RestTemplateCustomizer接口的匿名实现类执行customize方法 此时将真正执行lombda表达式

image-20220510211528353

回到 restTemplateCustomizer 方法 看这个lombad表达式都做了什么

image-20220510212350549

首先拿到容器中的loadBalancerInterceptor拦截器,然后给restTemplate对象添加

而loadBalancerInterceptor拦截器 就是来完成负载均衡的

#java求职##Java#
全部评论
看了你的分享,觉得没有啥东西是简单的
点赞 回复 分享
发布于 2022-05-19 21:25

相关推荐

12-07 16:52
已编辑
蚌埠坦克学院 Java
timeline技术1面 11.22技术2面 + hr 11.28这家公司很好,作息规律 10-10点半弹性打卡 晚上6点下班 双休,秋招hc少,很多都转正。语言kotolin + akka等 要转。一、技术1面1. 自我介绍(名字、学校、专业、项目)2. 问有没有offer、到岗时间3. 项目1:我负责的模块有哪些(流媒体、权限模块)4. 说完之后,我讲流媒体模块的功能 怎么设计 (分片上传,流媒体转码)5. 流媒体模块经过优化的(从之间传-》分片、从限定上传格式-》使用ffpeg转码)6. 流媒体哪部分使用了redis,我视频id和视频在minio的访问地址,存入redis提升性能。7. 还问了:项目服务器集群,5台流媒体模块(计算资源)、3台(机构、用户)、2台(minio以及redis存储相关)8. 问:集群能不能横向扩展? (使用微服务架构、后台管理模块通过nacos + 远程调用通信、流媒体模块计算资源使用消息队列 + xxljob定时任务,扩展机器主要提供资源、任务统一调度)9. 问:项目难点  (分片相关的,数据格式转换的、团队合作,需求调整,整体比较复杂)10. 问:遇到难点,怎么解决(你的技术思路是怎么来的) (第一从学习项目里面的某些场景获取、第二从csdn或者技术书籍上面)11. rpc框架部分 (项目描述,是自己开发,主要是为了实现轻量化的自定义的rpc框架、结合自己的使用需求定制)12. rpc:zookeeper的选举策略(没回答上来)13. 问:redis的使用(项目1 用了、rpc用在服务列表保存部分)14. 问:rpc的难点(netty的LTC解码器解决粘包半包,然后自定义协议,实现调用命令的传输)15. 八股:redis的使用16. 八股:集合,用过哪些(线程安全 + 线程不安全的集合)17. 八股:ConcurrentHashMap的底层原理(我是按照1.7 和 1.8的介绍)分段锁和细粒度锁,以及链表 | 链表 + 红黑树18. 八股:内存模型 happensBefore规则,(我没回答上来,但是说了大概是干嘛的)19. 八股:垃圾回收算法 + G1的整体思路20. 八股:AQS抽象队列同步器,作用,干嘛的,底层框架,实现锁机制21. 自我评价(觉得自己怎么样)我主要针对 公司的兴趣(游戏)、我对技术的兴趣(喜欢开发)、喜欢钻研了解新东西22. 反问(部门是具体做什么的、面试流程 2技术 + 1hr) 语言(Java kotolin netty redis zookeeper)做的是slg游戏(策略游戏)23. 问:我平时玩啥?我说steam的策略游戏 + fps (主要文明6 钢铁雄心 游族的大皇帝)二、技术2面面试官:感觉是hr自我介绍(老样子 + 项目) 同时说对游戏比较感兴趣介绍一下项目(我主要说了第一个,流媒体,图文,权限模块,以及具体的实现思路 技术选型等内容,包括后续的测试 和 上线运维 CICD devops 以及Jenkins相关的设计问:我了解游戏开发的工作吗?问:我玩哪些游戏吗?(SLG策略游戏,我说游族的页游还有手游)问:我想在这个实习里面学到什么,获取什么东西?反问:最后一面(是,hr面)反问:12月12-15到岗可以吗?(回答,需要和主管商量)综合评价:面试不难,主要是自我介绍,加项目的介绍,后续看视频(基本是商业化面试的思路,复述了一遍)#游族##面经##牛客创作赏金赛#
查看27道真题和解析 牛客创作赏金赛
点赞 评论 收藏
分享
1. C++中的引用和指针有什么区别?2. 什么是 RAII?它有什么好处?3. C++11引入的nullptr有什么作用?4. 如何实现一个单例模式?5. C++中的const关键字有什么用?如何使用?6. 什么是内存对齐?为什么需要内存对齐?7. C++中的虚表和虚指针是什么?8. 解释一下深拷贝和浅拷贝的区别。9. 如何使用std::shared_ptr和std::unique_ptr管理动态内存?10. 什么是函数模板和类模板?它们有什么区别?11. C++中的友元函数和友元类有什么作用?12. 解释一下C++中的多重继承及其问题。13. C++中的类型转换有哪些方式?分别是什么?14. 什么是模板特化?如何使用?15. C++中的异常处理机制是怎样的?16. 什么是 lambda 表达式?它的用途是什么?17. C++中的std::move和std::forward的区别是什么?18. 解释一下C++中的析构函数的作用和使用场景。19. C++中的标准库容器有哪些?它们的特点是什么?20. 什么是C++中的命名空间?它有什么作用?21. C++中的类型推导是什么?如何使用auto关键字?22. C++中的static关键字有什么作用?23. C++中的虚函数表是如何工作的?24. 解释一下C++中的内存泄漏及其解决方法。25. C++中的std::thread是如何实现的?26. 什么是条件变量?它在多线程中有什么作用?27. 解释一下C++中的编译期和运行期多态。28. C++中如何实现运算符重载?29. C++中的std::pair和std::tuple有什么区别?30. 什么是C++中的智能指针?它们的类型和使用场景是什么?答案附在面经中  c++/嵌入式面经专栏-牛客网 https://www.nowcoder.com/creation/manager/columnDetail/MJNwoM
查看30道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务