Spring Cloud:自定义 Ribbon 负载均衡策略

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
传统型负载均衡 CLB,每月750个小时 15LCU
简介: Spring Cloud:自定义 Ribbon 负载均衡策略

在前两篇文章中,我对 Ribbon 的使用做了详细的介绍:

Spring Cloud:使用Ribbon实现负载均衡详解(上)

Spring Cloud:使用Ribbon实现负载均衡详解(下)


但是使用的是 Ribbon 自带的负载均衡策略,那么 Ribbon 是否可以根据实际情况,自定义负载均衡策略呢?答案是肯定的,这一篇文章主要来介绍一下 Ribbon 如何自定义负载均衡策略。


1. 主启动类处理


还是使用上一节的客户端代码,先回忆一下相关内容:三个订单服务提供者,服务名称叫:MICROSERVICE-ORDER,端口分别为 8001、8002 和 8003。Eureka 集群三个服务,端口分别为 7001、7002 和 7003。


上一节主要是使用 Ribbon 的轮询和随机策略,来测试负载均衡。这一节我们自定义一个策略。首先要在启动类中添加 @RibbonClient 注解,如下:


@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "MICROSERVICE-ORDER", configuration = MyRuleConfig.class)
public class OrderConsumer {
   public static void main(String[] args) {
       SpringApplication.run(OrderConsumer.class, args);
   }
}

name 用来指定需要均衡的服务,即三个订单服务,configuration 用来指定所用的策略配置,这里使用我们自定义的一个配置 MyRuleConfig。接下来,我们来定义这个配置。


2. 自定义配置


这个配置的位置有个地方需要注意:就是所在的包不能和主启动类在同一个包下面,这是官方文档提到的注意事项。所以我们自己新建一个和主启动类所在的包同级的包,然后写 MyRuleConfig。


/**
* 自定义规则
* @author shengwu ni
*/
@Configuration
public class MyRuleConfig {
   @Bean
   public IRule myselfRule() {
       // 指定策略:我们自定义的策略
       return new CustomRule();
   }
}


3. 自定义策略


OK,接下来就是实现这个自定义策略:CustomRule了。我们假设自己定义的策略如下:


还是按照轮询的方式来选择服务,但是每个被轮询到的服务,接下来访问4次(默认是1次),4次访问完之后,再切换到下一个服务,访问4次,以此类推。


拿到这个需求之后,我们需要改写策略了,根据官方 github 源码可以知道,类似于轮询、随机这种策略,都是继承了 AbstractLoadBalancerRule 类,然后重写 choose 方法。所以,自定义策略分两步走:


  • 实现 AbstractLoadBalancerRule 类
  • 重写 choose 方法



我先把代码复制一下,然后来分析一下:


/**
* 自定义规则
* @author shengwu ni
*/
public class CustomRule extends AbstractLoadBalancerRule {
   /**
    * 总共被调用的次数,目前要求每台被调用4次
     */
   private int total = 0;
   /**
    * 当前提供服务列表的索引
    */
   private int currentIndex = 0;
   @Override public void initWithNiwsConfig(IClientConfig iClientConfig) {
   }
   /**
    * 在choose方法中,自定义我们自己的规则,返回的Server就是具体选择出来的服务
    * 自己的规则:按照轮询的规则,但是每个被轮询到的服务调用5次。
    * @param o
    * @return
    */
   @Override public Server choose(Object o) {
       // 获取负载均衡器lb
       ILoadBalancer lb = getLoadBalancer();
       if (lb == null) {
           return null;
       }
       Server server = null;
       while (server == null) {
           if (Thread.interrupted()) {
               return null;
           }
           // 获取可用服务列表
           List<Server> upList = lb.getReachableServers();
           // 获取所有服务列表
           List<Server> allList = lb.getAllServers();
           int serverCount = allList.size();
           if (serverCount == 0) {
               return null;
           }
           // 若调用次数小于4次,一直调用可用服务列表中索引为 currentIndex 的服务
           if(total < 4)
           {
               server = upList.get(currentIndex);
               total++;
           } else {
               // 到了4次之后,服务列表中的索引值++,表示下一个调用下一个服务
               total = 0;
               currentIndex++;
               // 当索引大于可用服务列表的size时,要重新从头开始
               currentIndex = currentIndex % upList.size();
               if (server == null) {
                   Thread.yield();
                   continue;
               }
               if (server.isAlive()) {
                   return (server);
               }
               server = null;
               Thread.yield();
           }
       }
       return server;
   }
}

我来简单分析一下代码:首先获取 ILoadBalancer 对象,该对象可以获取当前的服务。我们需要获取当前可用的服务列表和当前所有的服务列表。


total 表示服务被调用的次数,到4次,该服务调用停止,切换到下一个可用服务;currentIndex 表示当前可用服务列表中的索引。若调用次数小于4次,一直调用可用服务列表中索引为 currentIndex 的服务,到了4次之后,服务列表中的索引值++,表示下一个调用下一个服务。具体可以看代码中的注释。


4. 测试一下


OK,到这里,自定义的负载均衡策略就完成了,我们启动三个 eureka 集群和三个订单服务提供者,然后启动消费方客户端(端口9001),然后仍然在浏览器输入:

http://localhost:9001/consumer/order/get/1 来测试一下即可。


正常情况:当前订单提供服务会被调用四次,然后切换到另一个订单服务,轮流切换。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
负载均衡 Java Nacos
Ribbon负载均衡
Ribbon负载均衡
131 1
Ribbon负载均衡
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
1085 61
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
11月前
|
负载均衡 Java Nacos
常见的Ribbon/Spring LoadBalancer的负载均衡策略
自SpringCloud 2020版起,Ribbon被弃用,转而使用Spring Cloud LoadBalancer。Ribbon支持轮询、随机、加权响应时间和重试等负载均衡策略;而Spring Cloud LoadBalancer则提供轮询、随机及Nacos负载均衡策略,基于Reactor实现,更高效灵活。
733 0
|
负载均衡 Java 开发者
Ribbon框架实现客户端负载均衡的方法与技巧
Ribbon框架为微服务架构中的客户端负载均衡提供了强大的支持。通过简单的配置和集成,开发者可以轻松地在应用中实现服务的发现、选择和负载均衡。适当地使用Ribbon,配合其他Spring Cloud组件,可以有效提升微服务架构的可用性和性能。
198 0
|
4月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
889 0
|
5月前
|
人工智能 Java 测试技术
Spring Boot 集成 JUnit 单元测试
本文介绍了在Spring Boot中使用JUnit 5进行单元测试的常用方法与技巧,包括添加依赖、编写测试类、使用@SpringBootTest参数、自动装配测试模块(如JSON、MVC、WebFlux、JDBC等),以及@MockBean和@SpyBean的应用。内容实用,适合Java开发者参考学习。
632 0
|
1月前
|
JavaScript Java Maven
【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!
SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础
283 3
|
1月前
|
Java 测试技术 数据库连接
【SpringBoot(四)】还不懂文件上传?JUnit使用?本文带你了解SpringBoot的文件上传、异常处理、组件注入等知识!并且带你领悟JUnit单元测试的使用!
Spring专栏第四章,本文带你上手 SpringBoot 的文件上传、异常处理、组件注入等功能 并且为你演示Junit5的基础上手体验
838 2
|
8月前
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
396 0

热门文章

最新文章