微服务【Ribbon负载均衡&源码解析&饥饿加载】第2章

简介: 本文主要介绍:1,Ribbon负载均衡原理 2,源码跟踪 3,负载均衡策略 4,饥饿加载

1,负载均衡原理

1.1:负载均衡原理

SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的

负载均衡流程图:

image.gif编辑

那么我们发出的请求明明是http://userservice/user/1,怎么变成了http://localhost:8081的呢?

具体Ribbon什么时候拦截下来的请求?什么时候从注册中心拉取下来的?什么时候做的负载均衡呢?下面我们进入idea中分析源码

1.2:源码跟踪

首先看到restTemplate被LoadBalanced进行标记,意思就是说

通过restTemplate发起的请求会被LoadBalanced进行处理拦截

image.gif编辑

那么这个拦截的动作在底层中是通过谁进行完成的呢?就是:LoadBalancerInterceptor

1)LoadBalancerInterceptor

首先在编辑器中Ctrl+Shift+N搜索 LoadBalancerInterceptor 该实现类

image.gif编辑

点进去查看一下源码:该实现类实现了ClientHttpRequestInterceptor接口,那么这个接口是干嘛的呢?

image.gif编辑

 该接口是客户端请求拦截器,那么restTemplate不就是一个发Http请求的客户端嘛!被拦截image.gif编辑

既然实现类实现了ClientHttpRequestInterceptor接口,也实现了接口中的intercept方法,下面看一下这个方法具体在干嘛!(打个断点演示一下,图片放大更清楚)

image.gif编辑

可以看到这里的intercept方法,拦截了用户的HttpRequest请求,然后做了几件事:

    • request.getURI()获取请求uri,本例中就是http://service-provide/echo/love
    • originalUri.getHost()获取uri路径的主机名,其实就是服务id,service-provide
    • this.loadBalancer.execute()处理服务id,和用户请求

    这里的this.loadBalancerLoadBalancerClient类型,我们继续跟入。  

    2)LoadBalancerClient

    继续跟入execute方法:

    image.gif编辑

    跟入到此接口中:

    image.gif编辑

    跟入到接口的实现类中:

    image.gif编辑

    总结:

    跟踪到execute方法中,将参数服务Id传递进来交给Load Balancer函数进行处理,

    返回出:动态服务列表负载均衡器。

    这个负载均衡器是干嘛的?

    通过服务Id获取到服务注册中心的服务列表,现在这一步已经把服务拉取到了

    image.gif编辑  

    下一步进行负载均衡

    3)负载均衡策略IRule

    在刚才的代码中,可以看到获取服务使通过一个getServer方法来做负载均衡:

    image.gif编辑

    我们继续跟入:

    image.gif编辑

    继续跟踪源码chooseServer方法,发现这么一段代码:  

    image.gif编辑

    我们看看这个rule是谁:

    image.gif编辑

    对象是IRule对象,我们知道I是接口,Rule是规则,那么就是规则接口,那接口有实现类,咱们Ctrl+H查看一下继承树

    image.gif编辑

    image.gif编辑到这里,整个负载均衡的流程我们就清楚了。

    4)总结

    SpringCloudRibbon的底层采用了一个拦截器,拦截了RestTemplate发出的请求,对地址做了修改。用一幅图来总结一下:

    image.gif编辑

    基本流程如下:

      • 拦截我们的RestTemplate请求http://localhost:8071/fangwen/love
      • RibbonLoadBalancerClient会从请求url中获取服务名称
      • DynamicServerListLoadBalancer根据user-service到nacos拉取服务列表
      • nacos返回列表
      • IRule利用内置负载均衡规则,从列表中选择一个,
      • RibbonLoadBalancerClient修改请求地址,发起真实请求

      1.3:负载均衡策略

      1.3.1:负载均衡策略

      负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类:

      image.gif编辑

      不同规则的含义如下:

      image.gif编辑

      默认的实现就是ZoneAvoidanceRule,是一种轮询方案  

      1.3.2:自定义负载均衡策略

      通过定义IRule实现可以修改负载均衡规则,有两种方式

        1. 代码方式:在order-service中的OrderApplication类中,定义一个新的IRule:
        @Bean
        public IRule randomRule(){
            return new RandomRule();
        }

        image.gif

            2. 配置文件方式:在application.yml文件中,添加新的配置也可以修改规则:

        userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
          ribbon:
            NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则

        image.gif

        注意,一般用默认的负载均衡规则,不做修改。

        1.4:饥饿加载

        Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。

        什么意思呢?(访问监测一下)

        第一次请求:请求耗时如此之长

        image.gif编辑

        第二次请求:请求耗时很短

        image.gif编辑

        为什么会有这种变化呢?

        当然导致请求耗时过长的因素有很多,在这里最重要的一个因素是Ribbon采用了懒加载。

        那么何为懒加载?

        即第一次访问时才会去创建LoadBalanceClient,去服务注册中心拉取服务,导致时间加载过长。

        为了解决第一次访问才创建LoadBalanceClient导致耗时过长,可以采用饥饿加载。

        何为饥饿加载?

        饥饿加载则会在项目启动时进行创建,降低第一次访问的耗时,通过下面配置yml文件开启饥饿加载:

        ribbon:

         eager-load:

           enabled: true   # 开启饥饿加载

           clients: userservice   # 指定对userservice这个服务饥饿加载

        相关实践学习
        每个IT人都想学的“Web应用上云经典架构”实战
        本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
        相关文章
        |
        人工智能 安全 Java
        智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
        智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
        517 5
        |
        算法 测试技术 C语言
        深入理解HTTP/2:nghttp2库源码解析及客户端实现示例
        通过解析nghttp2库的源码和实现一个简单的HTTP/2客户端示例,本文详细介绍了HTTP/2的关键特性和nghttp2的核心实现。了解这些内容可以帮助开发者更好地理解HTTP/2协议,提高Web应用的性能和用户体验。对于实际开发中的应用,可以根据需要进一步优化和扩展代码,以满足具体需求。
        1627 29
        |
        前端开发 数据安全/隐私保护 CDN
        二次元聚合短视频解析去水印系统源码
        二次元聚合短视频解析去水印系统源码
        662 4
        |
        JavaScript 算法 前端开发
        JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
        这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
        |
        移动开发 前端开发 JavaScript
        从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
        H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。
        |
        存储 前端开发 JavaScript
        在线教育网课系统源码开发指南:功能设计与技术实现深度解析
        在线教育网课系统是近年来发展迅猛的教育形式的核心载体,具备用户管理、课程管理、教学互动、学习评估等功能。本文从功能和技术两方面解析其源码开发,涵盖前端(HTML5、CSS3、JavaScript等)、后端(Java、Python等)、流媒体及云计算技术,并强调安全性、稳定性和用户体验的重要性。
        |
        机器学习/深度学习 自然语言处理 算法
        生成式 AI 大语言模型(LLMs)核心算法及源码解析:预训练篇
        生成式 AI 大语言模型(LLMs)核心算法及源码解析:预训练篇
        4366 1
        |
        监控 JavaScript 数据可视化
        建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
        智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
        759 7
        |
        负载均衡 JavaScript 前端开发
        分片上传技术全解析:原理、优势与应用(含简单实现源码)
        分片上传通过将大文件分割成多个小的片段或块,然后并行或顺序地上传这些片段,从而提高上传效率和可靠性,特别适用于大文件的上传场景,尤其是在网络环境不佳时,分片上传能有效提高上传体验。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
        |
        自然语言处理 数据处理 索引
        mindspeed-llm源码解析(一)preprocess_data
        mindspeed-llm是昇腾模型套件代码仓,原来叫"modelLink"。这篇文章带大家阅读一下数据处理脚本preprocess_data.py(基于1.0.0分支),数据处理是模型训练的第一步,经常会用到。
        607 0

        推荐镜像

        更多
      1. DNS