![JAR search and dependency download from the Maven repository](/logo.png)
com.github.fashionbrot.ribbon.rule.RoundRobinRule Maven / Gradle / Ivy
package com.github.fashionbrot.ribbon.rule;
import com.github.fashionbrot.ribbon.AbstractLoadBalancerRule;
import com.github.fashionbrot.ribbon.loadbalancer.ILoadBalancer;
import com.github.fashionbrot.ribbon.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author fashionbrot
* @version 0.1.0
* @date 2019/12/8 22:45
*/
@Slf4j
public class RoundRobinRule extends AbstractLoadBalancerRule {
private AtomicInteger nextServerCyclicCounter;
public RoundRobinRule() {
nextServerCyclicCounter = new AtomicInteger(0);
}
@Override
public Server choose(ILoadBalancer lb) {
if (lb == null) {
log.warn("no load balancer");
return null;
}
Server server = null;
int count = 0;
while (server == null && count++ < 10) {
List allServers = lb.getAllServers();
int serverCount = allServers.size();
if ( serverCount == 0) {
log.warn("No up servers available from load balancer allServers size: " + lb.getAllServers().size());
return null;
}
int nextServerIndex = incrementAndGetModulo(serverCount);
server = allServers.get(nextServerIndex);
if (server!=null && lb.getPing().isAlive(server,lb.enableLog())){
return server;
}
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: "
+ lb);
}
return server;
}
/**
* Inspired by the implementation of {@link AtomicInteger#incrementAndGet()}.
*
* @param modulo The modulo to bound the value of the counter.
* @return The next value.
*/
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next)) {
return next;
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy