携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
前言
Ribbon的负载均衡策略默认是轮询,但是它还提供了其他几种机制,均实现了IRule接口
AbstractLoadBalancerRule
这是个抽象类,主要是为设置和获取负载均衡器提供默认实现的类
RoundRobinRule
轮询,系统默认的负载均衡策略,按照顺序依次去访问服务
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
log.warn("no load balancer");
return null;
}
Server server = null;
int count = 0;
while (server == null && count++ < 10) {
List<Server> reachableServers = lb.getReachableServers();
List<Server> allServers = lb.getAllServers();
int upCount = reachableServers.size();
int serverCount = allServers.size();
if ((upCount == 0) || (serverCount == 0)) {
log.warn("No up servers available from load balancer: " + lb);
return null;
}
//这里会算出本次访问的索引下标位置
int nextServerIndex = incrementAndGetModulo(serverCount);
server = allServers.get(nextServerIndex);
if (server == null) {
/* Transient. */
Thread.yield();
continue;
}
if (server.isAlive() && (server.isReadyToServe())) {
return (server);
}
// Next.
server = null;
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: "
+ lb);
}
return server;
}
AvailabilityFilteringRule
这个策略实际上还是会先根据轮询策略选出一台机制,然后会判断这台机子是否可用,如果不可用则会继续轮询下一台,直到次数打到10为止。
WeightedResponseTimeRule
根据权重进行负载均衡,每个服务器都可以有权重,权重越高越优先访问,如果没有命中任何有权重的服务则默认会退化称为轮询策略
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
// get hold of the current reference in case it is changed from the other thread
List<Double> currentWeights = accumulatedWeights;
if (Thread.interrupted()) {
return null;
}
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
int serverIndex = 0;
// last one in the list is the sum of all weights
double maxTotalWeight = currentWeights.size() == 0 ? 0 : currentWeights.get(currentWeights.size() - 1);
// No server has been hit yet and total weight is not initialized
// fallback to use round robin
if (maxTotalWeight < 0.001d || serverCount != currentWeights.size()) {
server = super.choose(getLoadBalancer(), key);
if(server == null) {
return server;
}
} else {
// generate a random weight between 0 (inclusive) to maxTotalWeight (exclusive)
double randomWeight = random.nextDouble() * maxTotalWeight;
// pick the server index based on the randomIndex
int n = 0;
for (Double d : currentWeights) {
if (d >= randomWeight) {
serverIndex = n;
break;
} else {
n++;
}
}
server = allList.get(serverIndex);
}
if (server == null) {
/* Transient. */
Thread.yield();
continue;
}
if (server.isAlive()) {
return (server);
}
// Next.
server = null;
}
return server;
}
ZoneAvoidanceRule
根据机房和服务器进行负载均衡,这个主要适用于多机房部署的情况,一般用不到
BestAvailableRule
忽略请求失败的服务器,找到并发比较低的服务器
RandomRule
随机策略,随机抽取一个服务器
int index = rand.nextInt(serverCount);
server = upList.get(index);