SpringCloud-Netflix学习笔记08——自定义Ribbon负载均衡策略
前言
Ribbon默认的负载均衡策略是轮询,其实Ribbon还自带了其他的负载均衡策略,可以进行选择,有如下几种:
实现接口:IRule
不同实现类:
* 1、AvailabilityFilteringRule:会先过滤掉跳闸的或者访问故障的服务,对剩下的服务进行轮询~
* 2、RoundRobinRule:轮询(默认是这种策略)~
* 3、RandomRule:随机~
* 4、WeightedResponseTimeRule:按照分配的权重进行分配
* 5、RetryRule:会先按照轮询获取服务,如果服务获取失败,则在指定的时间内进行重试~
我们想要切换负载均衡策略的话,只需要将该策略注入Spring即可,会覆盖掉默认的轮询策略,如下:
@Bean
public IRule myRule(){
return new RandomRule(); //使用随机策略
}
当然关于Ribbon的配置不应该在ConfigBean中配置,ConfigBean只是用来配置RestTemplate的,我们新建一个 myrule
包,在包中新建一个类 TangRule
来配置Ribbon。目录结构如下:
@Configuration
public class TangRule { //关于Ribbon负载均衡策略的配置
//实现接口:IRule
/*不同实现类:
* 1、AvailabilityFilteringRule:会先过滤掉跳闸的或者访问故障的服务,对剩下的服务进行轮询~
* 2、RoundRobinRule:轮询(默认是这种策略)~
* 3、RandomRule:随机~
* 4、WeightedResponseTimeRule:按照分配的权重进行分配
* 5、RetryRule:会先按照轮询获取服务,如果服务获取失败,则在指定的时间内进行重试~
* */
@Bean
public IRule myRule(){
return new RandomRule();
}
}
重新启动之后,就是用的随机策略了。
自定义Ribbon负载均衡策略
仿照官方的代码,自定义一个负载均衡策略。
首先在myrule包中新建一个类 TangRandomRule
,继承 AbstractLoadBalancerRule
父类,我们要实现的负载均衡策略如下:
每一个服务访问5次,换下一个服务,循环往复
AbstractLoadBalancerRule
类代码如下:
package com.tang.myrule;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
//启动之后之后加载一次这个类
public class TangRandomRule extends AbstractLoadBalancerRule {
//每一个服务访问5次,换下一个服务
private int count = 0;
private int total = 0;
//@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
//每次刷新都会进入这个方法,返回一个服务
public Server choose(ILoadBalancer lb, Object key) {
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;
}
int availableCount = upList.size(); //可利用服务的数量
if(availableCount == 0){
return null;
}
server = upList.get(total);
if(server == null){
Thread.yield(); //跳过本次线程
continue;
}
if(server.isAlive()){
count++;
if(count == 5){
total++;
count = 0;
if(total == availableCount)
total = 0;
}
//System.out.println("count:" + count);
//System.out.println("total:" + total);
return server;
}
/*int index = chooseRandomInt(serverCount); //在全部服务中随机选取一个服务下标
server = upList.get(index); //在可用的服务中拿出这个随机选取的服务*/
/*if (server == null) { //可用服务中没有这个服务
Thread.yield(); //跳过本次线程
continue;
}
if (server.isAlive()) { //可用服务中包含这个服务
return (server); //返回这个服务(访问)
}*/
server = null;
Thread.yield();
}
return server;
}
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// TODO Auto-generated method stub
}
}
接着在 TangRule
中注入我们的策略覆盖掉默认的轮询策略即可。
@Configuration
public class TangRule { //关于Ribbon负载均衡策略的配置
//实现接口:IRule
/*不同实现类:
* 1、AvailabilityFilteringRule:会先过滤掉跳闸的或者访问故障的服务,对剩下的服务进行轮询~
* 2、RoundRobinRule:轮询(默认是这种策略)~
* 3、RandomRule:随机~
* 4、WeightedResponseTimeRule:按照分配的权重进行分配
* 5、RetryRule:会先按照轮询获取服务,如果服务获取失败,则在指定的时间内进行重试~
* */
@Bean
public IRule myRule(){
return new TangRandomRule();
}
}
需要注意的是,在服务启动时会加载一次这个类,而每次刷新都会重新执行 choose
方法,利用这个原理就可以实现自己的负载均衡策略了。
分类:
spring家族
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)