加入收藏 | 设为首页 | 会员中心 | 我要投稿 晋中站长网 (https://www.0354zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Windows > 正文

谈谈Dubbo负载均衡是如何实现的?

发布时间:2019-09-10 19:18:49 所属栏目:Windows 来源:程序员界的彭于晏
导读:dubbo的负载均衡全部由AbstractLoadBalance的子类来实现 RandomLoadBalance 随机 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。 获取invoker的数量 获取第一个invoker的权重,并复制给f

ConsistentHashSelector ,是 ConsistentHashLoadBalance 的内部类,一致性哈希选择器,基于 Ketama 算法。

  1. /** 
  2.  * 虚拟节点与 Invoker 的映射关系 
  3.  */ 
  4. private final TreeMap<Long, Invoker<T>> virtualInvokers; 
  5. /** 
  6.  * 每个Invoker 对应的虚拟节点数 
  7.  */ 
  8. private final int replicaNumber; 
  9. /** 
  10.  * 定义哈希值 
  11.  */ 
  12. private final int identityHashCode; 
  13. /** 
  14.  * 取值参数位置数组 
  15.  */ 
  16. private final int[] argumentIndex; 
  17.  1: ConsistentHashSelector(List<Invoker<T>> invokers, String methodName, int identityHashCode) { 
  18.  2: this.virtualInvokers = new TreeMap<Long, Invoker<T>>(); 
  19.  3: // 设置 identityHashCode 
  20.  4: this.identityHashCode = identityHashCode; 
  21.  5: URL url = invokers.get(0).getUrl(); 
  22.  6: // 初始化 replicaNumber 
  23.  7: this.replicaNumber = url.getMethodParameter(methodName, "hash.nodes", 160); 
  24.  8: // 初始化 argumentIndex 
  25.  9: String[] index = Constants.COMMA_SPLIT_PATTERN.split(url.getMethodParameter(methodName, "hash.arguments", "0")); 
  26.  10: argumentIndex = new int[index.length]; 
  27.  11: for (int i = 0; i < index.length; i++) { 
  28.  12: argumentIndex[i] = Integer.parseInt(index[i]); 
  29.  13: } 
  30.  14: // 初始化 virtualInvokers 
  31.  15: for (Invoker<T> invoker : invokers) { 
  32.  16: String address = invoker.getUrl().getAddress(); 
  33.  17: // 每四个虚拟结点为一组,为什么这样?下面会说到 
  34.  18: for (int i = 0; i < replicaNumber / 4; i++) { 
  35.  19: // 这组虚拟结点得到惟一名称 
  36.  20: byte[] digest = md5(address + i); 
  37.  21: // Md5是一个16字节长度的数组,将16字节的数组每四个字节一组,分别对应一个虚拟结点,这就是为什么上面把虚拟结点四个划分一组的原因 
  38.  22: for (int h = 0; h < 4; h++) { 
  39.  23: // 对于每四个字节,组成一个long值数值,做为这个虚拟节点的在环中的惟一key 
  40.  24: long m = hash(digest, h); 
  41.  25: virtualInvokers.put(m, invoker); 
  42.  26: } 
  43.  27: } 
  44.  28: } 
  45.  29: } 
  46. public Invoker<T> select(Invocation invocation) { 
  47.  // 基于方法参数,获得 KEY 
  48.  String key = toKey(invocation.getArguments()); 
  49.  // 计算 MD5 值 
  50.  byte[] digest = md5(key); 
  51.  // 计算 KEY 值 
  52.  return selectForKey(hash(digest, 0)); 
  53. private String toKey(Object[] args) { 
  54.  StringBuilder buf = new StringBuilder(); 
  55.  for (int i : argumentIndex) { 
  56.  if (i >= 0 && i < args.length) { 
  57.  buf.append(args[i]); 
  58.  } 
  59.  } 
  60.  return buf.toString(); 
  61. private Invoker<T> selectForKey(long hash) { 
  62.  // 得到大于当前 key 的那个子 Map ,然后从中取出第一个 key ,就是大于且离它最近的那个 key 
  63.  Map.Entry<Long, Invoker<T>> entry = virtualInvokers.tailMap(hash, true).firstEntry(); 
  64.  // 不存在,则取 virtualInvokers 第一个 
  65.  if (entry == null) { 
  66.  entry = virtualInvokers.firstEntry(); 
  67.  } 
  68.  // 存在,则返回 
  69.  return entry.getValue(); 

(编辑:晋中站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读