一致性hash负载均衡可以让参数相同的请求每次都陆由到相同的机器上。这种负载均衡的方式可以让请求相对平均,相比直接使用hash而言,当某些节点下线时,请求会平均到其他服务提供者。
普通一致性hash会把每个服务节点散列到环形上,然后把请求的客户端散列到环上,顺时针往前找第一个节点就是要调用的节点。
普通一致性hash也有一定的局限性,它的散列不一定均匀,容易造成某些节点压力大。因此Dubbo框架使用了优化过的ketama一致性hash,这种算法会为每个真实节点创建多个虚拟节点,让节点分配更均匀
一致性hash负载均衡源码
//获取方法名
String methodname = RpcUtils.getMethodname(invocation);
//以接口名和方法名拼接出key
String key = invokers.get(0).getUrl().getServerKey()+"."+methodname;
//把所有可以调用的invoker进行hash
int identityHashCode = System.identityHashCode(invokers);
ConsistentHashSelector<T> selector = (ConsistentHashSelector<T>)selectors.get(key);
if(selector == null || selector.identityHashCode != identityHashCode){
selectors.put(key,new ConsistentHashSelector<T>(invokers,methodname),identityHashCode);
selector = ()selectors.get(key);
}
//通过selector选择出一个invoker进行RPC调用
return selector.select(invocation);