Spring Cloud 实战 | 解密负载均衡Ribbon底层原理,包含实战源码

news2024/11/16 5:44:00

专栏集锦,大佬们可以收藏以备不时之需

Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html

Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html

Logback 详解专栏:https://blog.csdn.net/superdangbo/category_9271502.html

tensorflow专栏:https://blog.csdn.net/superdangbo/category_8691332.html

Redis专栏:https://blog.csdn.net/superdangbo/category_9950790.html

1024程序员节特辑文章:

1024程序员狂欢节特辑 | ELK+ 协同过滤算法构建个性化推荐引擎,智能实现“千人千面”

1024程序员节特辑 | 解密Spring Cloud Hystrix熔断提高系统的可用性和容错能力

1024程序员节特辑 | ELK+ 用户画像构建个性化推荐引擎,智能实现“千人千面”

1024程序员节特辑 | OKR VS KPI谁更合适?

1024程序员节特辑 | Spring Boot实战 之 MongoDB分片或复制集操作

Spring实战系列文章:

Spring实战 | Spring AOP核心秘笈之葵花宝典

Spring实战 | Spring IOC不能说的秘密?

国庆中秋特辑系列文章:

国庆中秋特辑(八)Spring Boot项目如何使用JPA

国庆中秋特辑(七)Java软件工程师常见20道编程面试题

国庆中秋特辑(六)大学生常见30道宝藏编程面试题

国庆中秋特辑(五)MySQL如何性能调优?下篇

国庆中秋特辑(四)MySQL如何性能调优?上篇

国庆中秋特辑(三)使用生成对抗网络(GAN)生成具有节日氛围的画作,深度学习框架 TensorFlow 和 Keras 来实现

国庆中秋特辑(二)浪漫祝福方式 使用生成对抗网络(GAN)生成具有节日氛围的画作

国庆中秋特辑(一)浪漫祝福方式 用循环神经网络(RNN)或长短时记忆网络(LSTM)生成祝福诗词

目录

  • 一、Ribbon发展历史和底层原理
  • 二、负载均衡策略
  • 三、Spring Cloud Ribbon实战
  • 四、Spring Cloud Ribbon常见问题和解决方案

在这里插入图片描述

一、Ribbon发展历史和底层原理

Ribbon 是 Netflix 开发的一个开源项目,主要用于实现客户端负载均衡。其发展历史可以追溯到 2013 年,随着 Spring Cloud 生态的发展,Ribbon 逐渐成为 Spring Cloud 的一部分,被广泛应用于微服务架构中。

  1. 负载均衡底层原理
    Ribbon 的负载均衡底层原理是通过 RestTemplate 发起请求时,根据配置的负载均衡策略选择服务提供者。以下是 Ribbon 支持的负载均衡策略:
  • RoundRobin(轮询):默认策略,按照顺序依次选择服务提供者。
  • Random(随机):随机选择服务提供者。
  • BestConnection(最佳连接):根据服务提供者的响应时间选择最短的那个。
  • Sentinel(围栏):根据服务提供者的响应时间进行降级处理。
  1. 适用场景
    Ribbon 适用于以下场景:
  • 集群中各个节点提供服务能力等同且无状态的场景。
  • 需要根据请求特征或响应时间进行负载均衡的场景。
  • 需要实现动态发现和负载均衡的微服务架构。
  1. 详细参数
    Ribbon 的配置主要通过 application.properties 或 application.yml 文件进行设置。以下是一些常用参数:
  • listOfServers:指定服务提供者的地址列表,用逗号分隔。
  • loadBalancer:负载均衡策略配置。
    • roundRobin:轮询策略配置,无特殊参数。
    • random:随机策略配置,无特殊参数。
    • bestConnection:最佳连接策略配置,可设置以下参数:
      timeout:连接超时时间,单位为毫秒。
      sentinel:围栏策略配置,可设置以下参数:
      stat:统计信息配置,包括:
      enabled:是否启用统计信息,默认 false。
      timeout:统计超时时间,单位为毫秒,默认 1000。
  1. 发展历史
  • 2013 年,Netflix 开发了 Ribbon,用于解决内部微服务架构的负载均衡问题。
  • 2017 年,Spring Cloud 项目收购了 Ribbon,并将其作为 Spring Cloud 的一部分进行维护和发展。
  • 至今,Ribbon 成为了 Spring Cloud 生态系统中重要的组成部分,被广泛应用于微服务架构。
  1. 总结
    Ribbon 是一个成熟且实用的负载均衡组件,其底层原理是通过 RestTemplate 发起请求时,根据配置的负载均衡策略选择服务提供者。通过调整负载均衡策略和参数,可以满足不同场景下的需求。随着 Spring Cloud 生态系统的发展,Ribbon 将继续完善和扩展其功能,为微服务架构提供更好的支持。

https://github.com/Netflix/ribbon

在这里插入图片描述

二、负载均衡策略

Ribbon 支持以下几种负载均衡策略:

  1. RoundRobin(轮询)
    轮询策略是 Ribbon 的默认负载均衡策略。它按照顺序依次选择服务提供者。以下是轮询策略的代码分析:
    在 Ribbon 中,轮询策略实现在 DefaultLoadBalancer 类中。DefaultLoadBalancer 继承自 AbstractLoadBalancer 类。以下是轮询策略的关键代码:
public class DefaultLoadBalancer extends AbstractLoadBalancer {  
    private final AtomicInteger index = new AtomicInteger(0);
    @Override  
    protected Server choose(Server[] servers) {  
        int currentIndex = index.getAndUpdate(i -> (i + 1) % servers.length);  
        return servers[currentIndex];  
    }  
}

在这个代码中,choose 方法是 Ribbon 负载均衡的核心方法。它接收一个服务器数组作为参数。index 原子变量用于记录当前轮询到的服务器索引。每次调用 choose 方法时,索引会加 1,并对服务器数组取模,得到一个新的索引。然后从新的索引位置取出对应的服务器作为负载均衡选择的结果。
2. Random(随机)
随机策略是另一种简单的负载均衡策略。它随机选择一个服务提供者。以下是随机策略的代码分析:

public class RandomLoadBalancer extends AbstractLoadBalancer {  
    @Override  
    protected Server choose(Server[] servers) {  
        int randomIndex = new Random().nextInt(servers.length);  
        return servers[randomIndex];  
    }  
}

在这个代码中,choose 方法通过 Random 类的 nextInt 方法生成一个随机整数,然后使用这个整数作为索引从服务器数组中选取一个随机的服务器。
3. BestConnection(最佳连接)
最佳连接策略会根据服务提供者的响应时间选择最短的那一个。以下是最佳连接策略的代码分析:

public class BestConnectionLoadBalancer extends AbstractLoadBalancer {  
    private final List<Server> sortedServers = new ArrayList<>();
    @Override  
    protected Server choose(Server[] servers) {  
        // 获取所有服务器的响应时间  
        List<Long> responseTimes = getResponseTimes(servers);
        // 对服务器按照响应时间进行降序排序  
        sortedServers.sort(Comparator.comparingLong(o -> o));
        // 返回响应时间最短的服务器  
        return sortedServers.get(0);  
    }
    private List<Long> getResponseTimes(Server[] servers) {  
        // 获取服务器响应时间的逻辑,这里省略  
    }  
}

在这个代码中,choose 方法首先获取所有服务器的响应时间,然后对服务器按照响应时间进行降序排序。最后返回响应时间最短的服务器。
4. Sentinel(围栏)
围栏策略是根据服务提供者的健康状况和权重进行负载均衡。以下是围栏策略的代码分析:

public class SentinelLoadBalancer extends AbstractLoadBalancer {  
    private final Map<Server, Integer> serverWeights = new HashMap<>();
    @Override  
    protected Server choose(Server[] servers) {  
        // 获取所有服务器的权重总和  
        int totalWeight = getTotalWeights(servers);
        // 初始化围栏统计信息  
        for (Server server : servers) {  
            serverWeights.put(server, 1);  
        }
        // 按照权重比例从服务器列表中选取一个服务器  
        int randomWeight = new Random().nextInt(totalWeight);  
        int currentWeight = 0;  
        for (Map.Entry<Server, Integer> entry : serverWeights.entrySet()) {  
            currentWeight += entry.getValue();  
            if (randomWeight < currentWeight) {  
                return entry.getKey();  
            }  
        }
        // 如果没有合适的服务器,则抛出异常  
        throw new IllegalStateException("No available server found");  
    }
    private int getTotalWeights(Server[] servers) {  
        // 获取服务器权重总和的逻辑,这里省略  
    }  
}

在这个代码中,choose 方法首先获取所有服务器的 权重总和,然后遍历服务器列表,根据权重比例随机选择一个服务器。如果在遍历过程中找不到合适的服务器(即随机权重小于当前权重),则返回当前服务器的引用。如果最终没有找到合适的服务器,则抛出异常。
围栏策略的优点是根据服务提供者的健康状况和权重进行负载均衡,可以确保请求分配得更均匀,同时避免了传统轮询策略可能导致的不公平问题。缺点是在服务器数量较少时,可能会导致请求次数较多的服务器承担更多的负载,而请求次数较少的服务器负载较轻。此外,围栏策略的实现较为复杂,需要维护服务器的权重信息。
在实际应用中,可以根据实际情况调整服务器的权重,以实现更精确的负载均衡。例如,可以根据服务器的处理能力、响应时间等因素设置不同的权重。

在这里插入图片描述

三、Spring Cloud Ribbon实战

Spring Cloud 负载均衡主要通过 Ribbon 来实现客户端负载均衡。下面将详细介绍如何使用 Spring Cloud Ribbon 实现负载均衡,包含完整代码示例。

  1. 添加依赖
    在项目的 pom.xml 文件中,添加 spring-cloud-starter-ribbon 依赖:
<dependency>  
    <groupId>org.springframework.cloud</groupId>  
    <artifactId>spring-cloud-starter-ribbon</artifactId>  
    <version>3.2.5</version>  
</dependency>  
  1. 启用 Eureka 服务注册
    在项目的主启动类上添加@EnableEurekaClient 注解,以启用 Eureka 服务注册。
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;  
import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication  
@EnableDiscoveryClient  
public class Application {  
    public static void main(String[] args) {  
        SpringApplication.run(Application.class, args);  
    }  
}
  1. 添加 Ribbon 配置
    在 application.properties 或 application.yml 文件中添加 Ribbon 的配置,例如:
spring:  
  application:  
    name: movie-service  
  cloud:  
    ribbon:  
      my-service:  
        listOfServers: http://user-service-1.com, http://user-service-2.com  
        loadBalancer:  
          ribbon:  
            sentinel:  
              timeout: 1000  
              stat:  
                enabled: false  

这里设置了负载均衡的策略为轮询(round-robin),并指定了 user-service-1.com 和 user-service-2.com 为服务提供者。
4. 使用@LoadBalanced 注解
在需要进行负载均衡的 RestTemplate 上添加@LoadBalanced 注解。

import org.springframework.cloud.client.loadbalancer.LoadBalanced;  
import org.springframework.web.client.RestTemplate;
public class MovieService {  
    @LoadBalanced  
    private RestTemplate restTemplate;
    // 使用 restTemplate 发起请求时,会自动进行负载均衡  
    public String callUserService(String userServiceUrl) {  
        return restTemplate.getForObject(userServiceUrl, String.class);  
    }  
}
  1. 测试负载均衡
    启动电影服务(MovieService)和用户服务(UserService),然后调用 movie 服务中的 callUserService 方法,观察请求地址是否进行了负载均衡。
    以上代码示例展示了如何使用 Spring Cloud Ribbon 实现客户端负载均衡。在实际项目中,还可以根据需求自定义负载均衡策略,如响应时间加权等。更多关于 Spring Cloud Ribbon 的详细使用方法,可以参考官方文档:http://cloud.spring.io/spring-cloud-static/Camden.SR7/#netflix-ribbon-starter

完整代码:https://github.com/Netflix/ribbon/blob/master/ribbon-examples/src/main/java/com/netflix/ribbon/examples/rx/template/RxMovieTemplateExample.java

在这里插入图片描述

四、Spring Cloud Ribbon常见问题和解决方案

在使用负载均衡 Ribbon 时,可能会遇到一些常见问题,以下是一些这些问题及其解决方案:

  1. 问题:服务注册中心发现的服务实例数量不一致
    解决方案:确保服务注册中心(如 Eureka、Zookeeper 等)中的服务实例数量与实际运行的服务实例数量一致。定期检查并删除已下线的服务实例。
  2. 问题:负载均衡策略失效
    解决方案:检查 Ribbon 的配置文件,确保负载均衡策略配置正确。如轮询、随机、最佳连接等。同时,确保 Ribbon 与其他组件(如 Spring Cloud、Netflix OSS 等)的集成正确无误。
  3. 问题:服务调用失败
    解决方案:检查服务提供者的运行状态,确保其正常运行。同时,检查服务提供者的接口地址和端口是否正确。
  4. 问题:Ribbon 配置不生效
    解决方案:确保 Ribbon 的配置文件(如 application.properties 或 application.yml)正确无误。同时,检查 Ribbon 相关依赖是否已正确添加。
  5. 问题:服务延迟较高
    解决方案:根据服务延迟情况,调整 Ribbon 的负载均衡策略。例如,将最佳连接策略中的超时时间设置合适值,以降低响应时间较长的服务实例的权重。
  6. 问题:服务降级处理不生效
    解决方案:检查 Ribbon 的围栏(Sentinel)策略配置,确保降级处理逻辑正确。如设置响应时间阈值,并对超过阈值的服务实例进行降级处理。
  7. 问题:多个相同服务实例的负载不均衡
    解决方案:在 Ribbon 配置文件中,为相同服务实例设置不同的权重,以实现负载均衡。
  8. 问题:客户端与服务端通信异常
    解决方案:检查客户端与服务端的网络连接,确保通信正常。如检查防火墙、路由器等网络设备配置,确保端口、IP 地址等设置正确。
  9. 问题:统计信息丢失
    解决方案:确保 Ribbon 的统计信息配置正确,如开启统计信息、设置统计超时时间等。通过查看 Ribbon 的统计信息,以便及时发现和处理潜在问题。
  10. 问题:资源消耗过高
    解决方案:根据实际业务需求和系统资源状况,调整 Ribbon 的配置。如降低连接数、设置合理的超时时间等,以降低资源消耗。
    总之,在使用 Ribbon 时,要密切关注其运行状态,及时发现并解决潜在问题。同时,根据实际需求调整 Ribbon 的配置,以确保负载均衡效果满足预期。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1141228.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

车载音频ADI-ADSP21569音频DSP开发

车载音频ADI-ADSP21489音频DSP开发 是否需要申请加入数字音频系统研究开发交流答疑群(课题组)?可加我微信hezkz17, 本群提供音频技术答疑服务,+群赠送蓝牙音频,车载DSP音频项目核心开发资料, 1 芯片手册 2 电路原理图

fl studio2023最新版本如何设置中文?

FL Studio编曲软件真的是个神器&#xff0c;不过一开始打开看到全是英文&#xff0c;有点头大&#xff0c;对吧&#xff1f;其实切换成中文版超级简单&#xff0c;只需要几个步骤就搞定啦&#xff01;我自己也是用中文版的&#xff0c;觉得用起来更得心应手&#xff0c;效率也提…

分享一个基于asp.net的供销社农产品商品销售系统的设计与实现(源码调试 lw开题报告ppt)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…

MySQL主从复制(基于GTID--事务ID方式)

目录 一、GTID相关概念1.GTID 是什么&#xff1f;2.GTID主从复制方式概念3.GTID的优缺点 二、GTID工作原理三、部署主从复制四、测试同步1.主库上新建数据库2.从库上查看是否同步成功 五、重设从库六、常见故障七、故障切换八、GTID的一些疑问1.为什么基于GTID的同步也要打开bi…

Dataworks API:调取 MC 项目下所有表单

文章目录 前言Dataworks API 文档解读GetMetaDBTableList 接口文档 API 调试在线调试本地调试运行环境账密问题请求数据进一步处理 小结 前言 最近&#xff0c;我需要对公司的数据资产进行梳理&#xff0c;这其中便包括了Dataworks各个项目下的表单。这些表单&#xff0c;作为…

Java进击框架:Spring-Test(六)

Java进击框架&#xff1a;Spring-Test&#xff08;六&#xff09; 前言单元测试模拟对象 集成测试上下文管理和缓存事务管理集成测试的支持类执行SQL脚本WebTestClientMockMvc JDBC测试支持其它注释 前言 Spring团队提倡测试驱动开发(TDD)。Spring团队发现&#xff0c;控制反转…

Ai创作系统ChatGPT网站源码+图文搭建教程+支持GPT4.0+支持ai绘画(Midjourney)

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…

北邮22级信通院数电:Verilog-FPGA(7)第七周实验(1):带使能端的38译码器全加器(关注我的uu们加群咯~)

北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客 关注作者的uu们可以进群啦~ 目录 方法一&#xff…

C嘎嘎之类和对象中

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;掌握c的初始化和销毁&#xff0c;熟练运用拷贝构造…

Tuxera NTFS2024破解版本下载

当您获得一台新 Mac 时&#xff0c;它只能读取 Windows NTFS 格式的 USB 驱动器。要将文件添加、保存或写入您的 Mac&#xff0c;您需要一个附加的 NTFS 驱动程序。Tuxera 的 Microsoft NTFS for Mac 是一款易于使用的软件&#xff0c;可以在 Mac 上打开、编辑、复制、移动或删…

python二次开发Solidworks:齿轮生成器

目录 1、参数 2、手动建模 2.1方程式驱动曲线画渐开线 2.2画基圆、齿根圆、分度圆和齿顶圆 2.3画单个齿廓 2.4以齿厚拉伸基圆草图 2.5以齿厚拉伸单齿廓草图 2.6阵列齿数个单齿 3、python自动化建模 4、总结 1、参数 模数 "m" 2 齿数"z" 50 压…

目标检测 YOLOv5 预训练模型下载方法

目标检测 YOLOv5 预训练模型下载方法 flyfish https://github.com/ultralytics/yolov5 https://github.com/ultralytics/yolov5/releases 可以选择自己需要的版本和不同任务类型的模型 后缀名是pt

hdlbits系列verilog解答(模块按名字)-22

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 此问题类似于模块。您将获得一个名为的 mod_a 模块&#xff0c;该模块按某种顺序具有 2 个输出和 4 个输入。您必须按名称将 6 个端口连接到顶级模块的端口&#xff1a; module mod_a ( output out1, output …

分享那些让你苦笑不得的Bug经历

文章目录 1. 缺少引号的字符串2. 单引号与双引号混淆3. 单词拼写错误4. 索引越界5. 忽略大小写6. 未初始化的变量7. 忘记递增或递减8. 死循环9. 迭代器越界10. 忘记保存更改结论 &#x1f389;欢迎来到Java学习路线专栏~那些让我苦笑不得的Bug经历 ☆* o(≧▽≦)o *☆嗨~我是IT…

ChatGPT与广泛应用:革新还是威胁?

文章目录 GPT的革新之处1. 内容创作助手2. 自动化客户支持3. 教育和培训4. 自然语言理解 GPT的潜在威胁1. 失业风险2. 质量和伦理问题 我们平时如何使用GPT&#xff1f;1. 内容创作2. 研究和学术3. 个人助手4. 内容过滤 结论 &#x1f389;欢迎来到AIGC人工智能专栏~ChatGPT与广…

win10下用cmake编译zlib并验证

需要的工具&#xff1a; zlib&#xff0c; 下载路径&#xff1a;zlib Home Site vs2017或其他版本 cmake 1. 下载zlib&#xff0c;创建build文件夹。 下载地址&#xff1a;zlib Home Site 这里下载到d:/build-libs文件夹下&#xff0c;得到zlib-1.3文件夹。 在…

Android13源码添加系统服务

本文基于Android 13的framework层添加系统接口&#xff0c;为应用层提供读写函数、以及执行命令! 添加接口 frameworks/base/core/java/android/app/IDevices.aidl package android.app; interface IDevices {//读取文件String readFile(String path);//写入文件void writeF…

hdlbits系列verilog解答(模块按位置)-21

文章目录 一、问题描述二、verilog源码三、仿真结果 一、问题描述 此问题类似于上一个&#xff08;模块&#xff09;。您将获得一个名为的 mod_a 模块&#xff0c;该模块按此顺序具有 2 个输出和 4 个输入。您必须按位置将 6 个端口按该顺序连接到顶级模块的端口 out1 、 out2…

Mac-postman存储文件目录

今天postman弹窗要求登录账号才可访问之前的API文档数据。 但是这postman的账号又是前同事的账号&#xff0c;我没有他的账号和密码啊。 登录了我自己的postman账号后&#xff0c;所有的api文档都不见了....我服了。 首先去屏幕左上角---> 前往 --->个人 然后键盘按显…