zoukankan      html  css  js  c++  java
  • 【Dubbo源码学习】负载均衡算法(2)-轮询算法的实现

    @Override
    protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {
    String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName();

    //活跃服务提供者集合
    ConcurrentMap<String, WeightedRoundRobin> map = methodWeightMap.get(key);
    if (map == null) {
    methodWeightMap.putIfAbsent(key, new ConcurrentHashMap<String, WeightedRoundRobin>());
    map = methodWeightMap.get(key);
    }
    int totalWeight = 0;
    long maxCurrent = Long.MIN_VALUE;
    long now = System.currentTimeMillis();
    Invoker<T> selectedInvoker = null;
    WeightedRoundRobin selectedWRR = null;

    //找出活跃的权重最大的服务提供者为目标服务提供者
    for (Invoker<T> invoker : invokers) {
    String identifyString = invoker.getUrl().toIdentityString();
    WeightedRoundRobin weightedRoundRobin = map.get(identifyString);
    int weight = getWeight(invoker, invocation);
    if (weight < 0) {
    weight = 0;
    }
    if (weightedRoundRobin == null) {
    weightedRoundRobin = new WeightedRoundRobin();
    weightedRoundRobin.setWeight(weight);
    map.putIfAbsent(identifyString, weightedRoundRobin);
    weightedRoundRobin = map.get(identifyString);
    }
    if (weight != weightedRoundRobin.getWeight()) {
    //weight changed
    weightedRoundRobin.setWeight(weight);
    }
    //每轮询一次,服务提供者的当前权限增长给定步长
    long cur = weightedRoundRobin.increaseCurrent();
    weightedRoundRobin.setLastUpdate(now);

    //当前服务提供者权重大于最大权重,最大权重修改为当前服务提供者权重,目标服务提供者设置为当前服务提供者
    if (cur > maxCurrent) {
    maxCurrent = cur;
    selectedInvoker = invoker;
    selectedWRR = weightedRoundRobin;
    }

    //用于重新目标服务提供者权重
    totalWeight += weight;
    }

    //回收活跃的服务提供者
    if (!updateLock.get() && invokers.size() != map.size()) {
    if (updateLock.compareAndSet(false, true)) {
    try {
    // copy -> modify -> update reference
    ConcurrentMap<String, WeightedRoundRobin> newMap = new ConcurrentHashMap<String, WeightedRoundRobin>();
    newMap.putAll(map);
    Iterator<Entry<String, WeightedRoundRobin>> it = newMap.entrySet().iterator();
    while (it.hasNext()) {
    Entry<String, WeightedRoundRobin> item = it.next();
    if (now - item.getValue().getLastUpdate() > RECYCLE_PERIOD) {
    it.remove();
    }
    }
    methodWeightMap.put(key, newMap);
    } finally {
    updateLock.set(false);
    }
    }
    }

    //目标服务提供者不为空,则将目标服务提供者权重设置为最低:current.addAndGet(-1 * total)
    if (selectedInvoker != null) {
    selectedWRR.sel(totalWeight);
    return selectedInvoker;
    }

    //返回第一个为目标服务提供者
    // should not happen here
    return invokers.get(0);
    }
  • 相关阅读:
    wsl 如何去掉 windows 的环境变量
    wget出现Unable to establish SSL connection
    openssh 升级
    element/JS文件上传和下载excel问题
    mysql操作过程中常见问题汇总
    [VB.NET Tips]线程传递参数四种方法
    主路由拨号_openwrt做旁路由_ipv4端口映射的设置
    Openwrt_Linux_crontab任务_顺序执行脚本
    Armbian_笔记
    Debian10_Centos8_fail2ban
  • 原文地址:https://www.cnblogs.com/walson/p/10243248.html
Copyright © 2011-2022 走看看