// 轮询算法实现publicclassRoundRobinRuleextendsAbstractLoadBalancerRule {
private AtomicInteger nextServerCyclicCounter;
publicRoundRobinRule() {
nextServerCyclicCounter = newAtomicInteger(0);
}
@Overridepublic Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
private Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
log.warn("no load balancer");
returnnull;
}
Serverserver=null;
intcount=0;
while (server == null && count++ < 10) {
List<Server> reachableServers = lb.getReachableServers();
List<Server> allServers = lb.getAllServers();
intupCount= reachableServers.size();
intserverCount= allServers.size();
if ((upCount == 0) || (serverCount == 0)) {
log.warn("No up servers available from load balancer: " + lb);
returnnull;
}
intnextServerIndex= incrementAndGetModulo(serverCount);
server = allServers.get(nextServerIndex);
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive() && (server.isReadyToServe())) {
return server;
}
server = null;
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: " + lb);
}
return server;
}
privateintincrementAndGetModulo(int modulo) {
for (;;) {
intcurrent= nextServerCyclicCounter.get();
intnext= (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next)) return next;
}
}
}
加权响应时间算法:
publicclassWeightedResponseTimeRuleextendsRoundRobinRule {
privatevolatile List<Double> accumulatedWeights = newArrayList<>();
@Overridepublic Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
returnnull;
}
Serverserver=null;
while (server == null) {
List<Double> currentAccumulatedWeights = accumulatedWeights;
if (Thread.interrupted()) {
returnnull;
}
doublemaxTotalWeight= currentAccumulatedWeights.size() == 0 ? 0 : currentAccumulatedWeights.get(currentAccumulatedWeights.size() - 1);
if (maxTotalWeight < 0.001d) {
server = super.choose(getLoadBalancer(), key);
return server;
}
doublerandomWeight= random.nextDouble() * maxTotalWeight;
intn=0;
for (Double weight : currentAccumulatedWeights) {
if (weight >= randomWeight) {
server = upList.get(n);
break;
}
n++;
}
if (server == null) {
server = super.choose(getLoadBalancer(), key);
}
}
return server;
}
}
2.3 Ribbon 与 Spring Cloud 整合
Ribbon 与 Spring Cloud 的整合是通过 LoadBalancerClient 接口实现的:
publicinterfaceLoadBalancerClientextendsServiceInstanceChooser {
<T> T execute(String serviceId, LoadBalancerRequest<T> request)throws IOException;
URI reconstructURI(ServiceInstance instance, URI original);
}
3. Spring Cloud LoadBalancer 深度解析
3.1 LoadBalancer 架构设计
Spring Cloud LoadBalancer 是 Spring 官方推出的负载均衡器,旨在替代 Ribbon: