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

发布时间:2025-09-01 01:50:12 作者:益华网络 来源:undefined 浏览量(0) 点赞(0)
摘要:阅读文本大概需要 3 分钟。 在前两篇文章中,我对 Ribbon 的使用做了详细的介绍: Spring Cloud:使用Ribbon实现负载均衡详解(上) Spring Cloud:使用Ribbon实现负载均衡详解(下

阅读文本大概需要 3 分钟。

在前两篇文章中,我对 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

*/
@Configurationpublic 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 upList = lb.getReachableServers();

           // 获取所有服务列表

           List 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 来测试一下即可。

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

二维码

扫一扫,关注我们

声明:本文由【益华网络】编辑上传发布,转载此文章须经作者同意,并请附上出处【益华网络】及本页链接。如内容、图片有任何版权问题,请联系我们进行处理。

感兴趣吗?

欢迎联系我们,我们愿意为您解答任何有关网站疑难问题!

您身边的【网站建设专家】

搜索千万次不如咨询1次

主营项目:网站建设,手机网站,响应式网站,SEO优化,小程序开发,公众号系统,软件开发等

立即咨询 15368564009
在线客服
嘿,我来帮您!