本文次要钻研一下dubbo-go的roundRobinLoadBalance

roundRobinLoadBalance

dubbo-go-v1.4.2/cluster/loadbalance/round_robin.go

const (    // RoundRobin ...    RoundRobin = "roundrobin"    // COMPLETE ...    COMPLETE = 0    // UPDATING ...    UPDATING = 1)var (    methodWeightMap sync.Map          // [string]invokers    state           = int32(COMPLETE) // update lock acquired ?    recyclePeriod   = 60 * time.Second.Nanoseconds())func init() {    extension.SetLoadbalance(RoundRobin, NewRoundRobinLoadBalance)}type roundRobinLoadBalance struct{}// NewRoundRobinLoadBalance ...func NewRoundRobinLoadBalance() cluster.LoadBalance {    return &roundRobinLoadBalance{}}
  • roundRobinLoadBalance的NewRoundRobinLoadBalance办法创立了roundRobinLoadBalance

Select

dubbo-go-v1.4.2/cluster/loadbalance/round_robin.go

func (lb *roundRobinLoadBalance) Select(invokers []protocol.Invoker, invocation protocol.Invocation) protocol.Invoker {    count := len(invokers)    if count == 0 {        return nil    }    if count == 1 {        return invokers[0]    }    key := invokers[0].GetUrl().Path + "." + invocation.MethodName()    cache, _ := methodWeightMap.LoadOrStore(key, &cachedInvokers{})    cachedInvokers := cache.(*cachedInvokers)    var (        clean               = false        totalWeight         = int64(0)        maxCurrentWeight    = int64(math.MinInt64)        now                 = time.Now()        selectedInvoker     protocol.Invoker        selectedWeightRobin *weightedRoundRobin    )    for _, invoker := range invokers {        var weight = GetWeight(invoker, invocation)        if weight < 0 {            weight = 0        }        identifier := invoker.GetUrl().Key()        loaded, found := cachedInvokers.LoadOrStore(identifier, &weightedRoundRobin{weight: weight})        weightRobin := loaded.(*weightedRoundRobin)        if !found {            clean = true        }        if weightRobin.Weight() != weight {            weightRobin.setWeight(weight)        }        currentWeight := weightRobin.increaseCurrent()        weightRobin.lastUpdate = &now        if currentWeight > maxCurrentWeight {            maxCurrentWeight = currentWeight            selectedInvoker = invoker            selectedWeightRobin = weightRobin        }        totalWeight += weight    }    cleanIfRequired(clean, cachedInvokers, &now)    if selectedWeightRobin != nil {        selectedWeightRobin.Current(totalWeight)        return selectedInvoker    }    // should never happen    return invokers[0]}
  • Select办法遍历invokers,通过weightRobin.increaseCurrent()作为currentWeight,若currentWeight大于maxCurrentWeight则更新maxCurrentWeight,设置selectedInvoker为以后invoker,设置selectedWeightRobin为以后weightRobin;之后对于selectedWeightRobin不为nil的执行selectedWeightRobin.Current(totalWeight),返回selectedInvoker

小结

roundRobinLoadBalance的NewRoundRobinLoadBalance办法创立了roundRobinLoadBalance;其Select办法遍历invokers,通过weightRobin.increaseCurrent()作为currentWeight,若currentWeight大于maxCurrentWeight则更新maxCurrentWeight,设置selectedInvoker为以后invoker,设置selectedWeightRobin为以后weightRobin

doc

  • round_robin