Ribbon默认的负载均衡算法为轮循算法,还提供了随机和重试等负载均衡算法
但如果要自定义Ribbon的负载均衡算法呢,例如,自定义一个负载均衡算法为连续五个请求请求同一个微服务,一次轮循下去。
- 在启动类上添加注解
@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MyRule.class)
注意,十分重要,MyRule类不能建在被@ComponetScan扫描到包及子包里面。我建在的位置在这里
- 建一个配置类
@Configuration
public class MyRule {
@Bean
public IRule myRule1(){
return new MyRoundRule();
}
}
- 建一个负载均衡算法的类
public class MyRoundRule extends AbstractLoadBalancerRule {
private AtomicInteger currentIndex=new AtomicInteger(0);
private AtomicInteger total=new AtomicInteger(0);
/**
* Randomly choose from all living servers
*/
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) {
/*
* No servers. End regardless of pass, because subsequent passes
* only get more restrictive.
*/
return null;
}
//int index = chooseRandomInt(1);
//server = upList.get(index);
if(total.get()<5){
total.getAndAdd(1);
server=upList.get(currentIndex.get());
}else{
total.set(0);
int index=currentIndex.getAndAdd(1);;
if(index>=upList.size()-1){
currentIndex.set(0);
}
}
if (server == null) {
/*
* The only time this should happen is if the server list were
* somehow trimmed. This is a transient condition. Retry after
* yielding.
*/
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Shouldn't actually happen.. but must be transient or a bug.
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
}
}
到此,自定义的负载均衡算法大功告成!