三种负载均衡 Nginx、Dubbo、Ribbon 区别
描述
1.Dubbo负载均衡:支持4种(随机,轮循,最少活跃,hash),引入了JVM预热时间加权、权重自定义配置的规则,同时支持控制台动态配置权重值参数,所以是最灵活的。
2.Nginx负载均衡:支持4种,自带 轮询(支持权重)、IP_Hash(避免Session共享的问题)、最少连接数策略,可以扩展fair(响应时间)策略,更专注于功能。
3.Ribbon负载均衡:支持6种,不支持权重:轮询、随机、最少连接数、最短响应时间(随机+响应时间加权)、过滤异常节点+轮询,负载策略最全的
Dubbo 负载均衡(2.6.x)
Dubbo提供4种负载均衡算法,引入了JVM预热时间加权、权重自定义配置的规则,同时支持控制台动态配置权重值参数,所以最灵活。
Random LoadBalance:
按照权重随机分配Provider,比如随机且权重Node1:Node2= 2:1,那么运行30次,大约有20次在Node1上,10次在Node2上。RoundRobin LoadBalance:
按照权重轮询分配。比如权重Node1:Node2= 20:10
,那么运行30次:前20次里面轮询Node1和Node2大家各10次,第20次到30次,全部选择Node1。因为Dubbo默认是不会做公约数的处理,只有完成一个完整的20+10次运算,才能保证负载均衡的权重比例准确,如果Consumer只调用了20次,那么这里配置的权重的结果就是1:1了,该算法很不平滑。在2.6.5版本中修复了,跟Nginx的实现方法一样。LeastActive LoadBalance:
节点处理越快分配更多,避免慢节点堆积,每次筛选Provider的时候,都只取Active值最小的节点,如果最小Active
值的节点有多个,则按照权重随机选取。Provider
每获取到一个任务Active值++,每结束一个任务Active值--。ConsistentHash LoadBalance:
唯一忽略权重配置和JVM预热的算法。先把所有Provider
都分配160个虚拟节点,通过Hash算法,全部分散到Hash圆上。每次Consumer
调用时,会根据参数值做Hash换算,最后映射到Hash圆上,找到邻近的虚拟节点,最终获取到提供服务的Provider。但是Dubbo在实现的时候违背了Hash
一致性的原则,每次Porvider发生改变的时候(新增或者剔除),都会重新创建一个Hash圆,而不是在之前的Hash圆上新增或者剔除不合格的Porvider。
Nginx 负载均衡算法
Nginx目前有4种负载均衡配置:
round_robin
,加权轮询,是默认的HTTP负载均衡算法,适用于知道机器的性能,且默认所有的请求对于服务器而言,处理的时间相差不大。比如我Server1 比Server2的配置要高一倍,我设置为2:1的权重,可以实现比较科学的负载。算法实现上,简单的轮询很简单,给每个Server依次编号,然后只要记录一个调用index,既可以实现轮询。ip_hash
,IP哈希,可保持会话least_conn
; 避免了慢堆积,会取连接数最小的server提供服务,可以避免有些请求耗时长,有些耗时端的情况。根据实际的连接数选择服务器。fair
,需要插件扩展该功能,根据后端服务器的响应时间来分配请求,响应时间短的优先分配,避免慢堆积。权重配置
:而且采用的是平滑的负载均衡算法,比如node1:node2:node3=1:2:5 --> node3,node3,node2,node3,node1,node3,node2,node3
。
Ribbon 负载均衡概述
RoundRobinRule
:轮询。默认超过10次获取到的server都不可用,会返回一个空的serverRandomRule
:随机,如果随机到的server为null或者不可用的话,会while不停的循环选RetryRule
:一定时限内循环重试。默认继承RoundRobinRule
,也支持自定义注入,RetryRule
会在每次选取之后,对选举的server进行判断,是否为null,是否alive,并且在500ms内会不停的选取判断。而RoundRobinRule失效的策略是超过10次,RandomRule是没有失效时间的概念,只要serverList没都挂。
@Bean
public IRule ribbonRule() {
return new RetryRule(new BestAvailableRule());//这里配置策略,和配置文件对应
}
BestAvailableRule
:最小连接数。遍历serverList,选取出可用的且连接数最小的一个server。该算法里面有一个LoadBalancerStats
的成员变量,会存储所有server的运行状况和连接数。如果选取到的server为null,那么会调用RoundRobinRule
重新选取。WeightedResponseTimeRule
:最小响应时间。这个策略整合了随机算法和响应时间加权算法。会开启定时任务,每30秒计算一次所有Provider的响应时间,以响应时间作为权重,响应时间越短的服务器被选中的概率越大。比如Node1:node2:node3
的平均响应时间为100ms:200ms:300ms
,那么nodes的的权重值是300:500:600,每次以600为基础*随机值,那么落在 0--300的概率为50%,300--500的概率33%,100--600的概率为17%,也就是平均响应时间越短的节点,被选中的概率越大。
double totalResponseTime = 0;
//遍历获取所有节点的总的平均响应时间
for (Server server : nlb.getAllServers()) {
ServerStats ss = stats.getSingleServerStat(server);
totalResponseTime += ss.getResponseTimeAvg();
}
Double weightSoFar = 0.0;
//然后从第一个节点开始设置自增的weightSoFar,每个结点的权重值weight为总响应时间-自己的相应时间,也就是说,node的响应时间越短,weight的值就越大,就越有可能被随机数命中
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);
}
setWeights(finalWeights);
AvailabilityFilteringRule
过滤+轮询策略,先过滤出故障的或并发请求大于阈值一部分服务实例,然后再轮询。
private boolean shouldSkipServer(ServerStats stats) {
if ((CIRCUIT_BREAKER_FILTERING.get() && stats.isCircuitBreakerTripped()) || stats.getActiveRequestsCount() >= activeConnectionsLimit.get()) {
return true;
}
return false;
}
ZoneAvoidanceRule
扩展了轮询策略,继承了2个过滤器:ZoneAvoidancePredicate
和AvailabilityPredicate
,除了过滤超时和链接数过多的server
,还会过滤掉不符合要求的zone
里面的所有节点。
原文链接:https://blog.csdn.net/washingtin/article/details/98468119