标签:++ sci cal oid active ribbon als 重试 available
Ribbon实现客户端的负载均衡,Feign内部是默认集成Ribbon的。本文会讲下Ribbon的几种配置方式。
设置Ribbon有两种方式,第一种是在@FeignClient中的configuration设置自定义的类
@FeignClient(value = "user", configuration = RibbonConfig.class)
Ribbon配置类RibbonConfig设置规则
@Configuration
public class RibbonConfig {
@Bean
public IRule ribbonRule() {
return new RandomRule(); //随机
}
}
第二种是在配置中定义规则(第一个值是服务名)
user.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.BestAvailableRule //空闲连接规则
for (Server server: serverList) {
ServerStats serverStats = loadBalancerStats.getSingleServerStat(server);
if (!serverStats.isCircuitBreakerTripped(currentTime)) {
int concurrentConnections = serverStats.getActiveRequestsCount(currentTime);
if (concurrentConnections < minimalConcurrentConnections) {
minimalConcurrentConnections = concurrentConnections;
chosen = server;
}
}
}
遍历所有实例,选出请求数最低的实例。
生成随机数获取实例。
根据实例数 1-N全部轮询一遍,然后再重头开始。
实例请求时间超过maxRetryMillis(500ms)时则会返回null并进行下一次请求,重试最多会尝试10次。
使用该规则时,WeightedResponseTimeRule内会启动一个线程DynamicServerWeightTask定期去更新每个实例的权重数,调用方法为maintainWeights。
public void maintainWeights() {
ILoadBalancer lb = getLoadBalancer();
if (lb == null) {
return;
}
if (!serverWeightAssignmentInProgress.compareAndSet(false, true)) {
return;
}
try {
logger.info("Weight adjusting job started");
AbstractLoadBalancer nlb = (AbstractLoadBalancer) lb;
LoadBalancerStats stats = nlb.getLoadBalancerStats();
if (stats == null) {
// no statistics, nothing to do
return;
}
double totalResponseTime = 0;
// 第一次遍历得到所有平均请求时间的合
for (Server server : nlb.getAllServers()) {
// this will automatically load the stats if not in cache
ServerStats ss = stats.getSingleServerStat(server);
totalResponseTime += ss.getResponseTimeAvg();
}
// weight for each server is (sum of responseTime of all servers - responseTime)
// so that the longer the response time, the less the weight and the less likely to be chosen
Double weightSoFar = 0.0;
// 第二次遍历把之前计算的合减去本次的平均请求时间
List<Double> finalWeights = new ArrayList<Double>();
for (Server server : nlb.getAllServers()) {
ServerStats ss = stats.getSingleServerStat(server);
double weight = totalResponseTime - ss.getResponseTimeAvg();
weightSoFar += weight;
finalWeights.add(weightSoFar);
}
//这里会把权重数放到全局变量accumulatedWeights中
setWeights(finalWeights);
} catch (Exception e) {
logger.error("Error calculating server weights", e);
} finally {
serverWeightAssignmentInProgress.set(false);
}
}
后面在调用choose的时候就会根据最大的权重数生成一个随机数,并遍历各实例的权重数,权重数大于随机数即选择该实例。
//maxTotalWeight是获取accumulatedWeights的最后一个权重数
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);
创建一个类,实现IRule即可自定义规则
public class MyRule implements IRule {
private ILoadBalancer loadBalancer;
@Override
public Server choose(Object key) {
//这里编写你规则的逻辑
List<Server> servers = loadBalancer.getAllServers();
return servers.get(0);
}
@Override
public void setLoadBalancer(ILoadBalancer lb) {
this.loadBalancer = lb;
}
@Override
public ILoadBalancer getLoadBalancer() {
return this.loadBalancer;
}
}
标签:++ sci cal oid active ribbon als 重试 available
原文地址:https://www.cnblogs.com/nicori/p/11672030.html