关于dubbo:聊聊dubbogo的leastActiveLoadBalance

40次阅读

共计 3430 个字符,预计需要花费 9 分钟才能阅读完成。

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

leastActiveLoadBalance

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

const (
    // LeastActive ...
    LeastActive = "leastactive"
)

func init() {extension.SetLoadbalance(LeastActive, NewLeastActiveLoadBalance)
}

type leastActiveLoadBalance struct {
}

// NewLeastActiveLoadBalance ...
func NewLeastActiveLoadBalance() cluster.LoadBalance {return &leastActiveLoadBalance{}
}
  • leastActiveLoadBalance 的 NewLeastActiveLoadBalance 办法创立 leastActiveLoadBalance

Select

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

func (lb *leastActiveLoadBalance) Select(invokers []protocol.Invoker, invocation protocol.Invocation) protocol.Invoker {count := len(invokers)
    if count == 0 {return nil}
    if count == 1 {return invokers[0]
    }

    var (
        leastActive  int32                = -1 // The least active value of all invokers
        totalWeight  int64                     // The number of invokers having the same least active value (LEAST_ACTIVE)
        firstWeight  int64                     // Initial value, used for comparison
        leastCount   int                       // The number of invokers having the same least active value (LEAST_ACTIVE)
        leastIndexes = make([]int, count)      // The index of invokers having the same least active value (LEAST_ACTIVE)
        sameWeight   = true                    // Every invoker has the same weight value?
    )

    for i := 0; i < count; i++ {invoker := invokers[i]
        // Active number
        active := protocol.GetMethodStatus(invoker.GetUrl(), invocation.MethodName()).GetActive()
        // current weight (maybe in warmUp)
        weight := GetWeight(invoker, invocation)
        // There are smaller active services
        if leastActive == -1 || active < leastActive {
            leastActive = active
            leastIndexes[0] = i
            leastCount = 1 // next available leastIndex offset
            totalWeight = weight
            firstWeight = weight
            sameWeight = true
        } else if active == leastActive {leastIndexes[leastCount] = i
            totalWeight += weight
            leastCount++

            if sameWeight && (i > 0) && weight != firstWeight {sameWeight = false}
        }
    }

    if leastCount == 1 {return invokers[0]
    }

    if !sameWeight && totalWeight > 0 {offsetWeight := rand.Int63n(totalWeight) + 1
        for i := 0; i < leastCount; i++ {leastIndex := leastIndexes[i]
            offsetWeight -= GetWeight(invokers[i], invocation)
            if offsetWeight <= 0 {return invokers[leastIndex]
            }
        }
    }

    index := leastIndexes[rand.Intn(leastCount)]
    return invokers[index]
}
  • Select 办法遍历 invokers,挨个通过 protocol.GetMethodStatus(invoker.GetUrl(), invocation.MethodName()).GetActive() 获取 active 信息,并通过 GetWeight(invoker, invocation) 获取 weight,而后计算 leastCount、totalWeight、sameWeight;对于 leastCount 为 1 的返回 invokers[0],对于 sameWeight 为 false 且 totalWeight 大于 0 的,遍历 leastIndexes,计算 offsetWeight,若 offsetWeight 小于等于 0,则返回 invokers[leastIndex],否则通过 leastIndexes[rand.Intn(leastCount)] 计算 index,返回 invokers[index]

GetWeight

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

// GetWeight ...
func GetWeight(invoker protocol.Invoker, invocation protocol.Invocation) int64 {url := invoker.GetUrl()
    weight := url.GetMethodParamInt64(invocation.MethodName(), constant.WEIGHT_KEY, constant.DEFAULT_WEIGHT)

    if weight > 0 {
        //get service register time an do warm up time
        now := time.Now().Unix()
        timestamp := url.GetParamInt(constant.REMOTE_TIMESTAMP_KEY, now)
        if uptime := now - timestamp; uptime > 0 {warmup := url.GetParamInt(constant.WARMUP_KEY, constant.DEFAULT_WARMUP)
            if uptime < warmup {if ww := float64(uptime) / float64(warmup) / float64(weight); ww < 1 {weight = 1} else if int64(ww) <= weight {weight = int64(ww)
                }
            }
        }
    }
    return weight
}
  • GetWeight 办法通过 url.GetMethodParamInt64(invocation.MethodName(), constant.WEIGHT_KEY, constant.DEFAULT_WEIGHT) 获取 weight,若 weight 大于 0,则计算 warmup,从新计算 weight 值

小结

leastActiveLoadBalance 的 NewLeastActiveLoadBalance 办法创立 leastActiveLoadBalance;Select 办法遍历 invokers,挨个通过 protocol.GetMethodStatus(invoker.GetUrl(), invocation.MethodName()).GetActive() 获取 active 信息,并通过 GetWeight(invoker, invocation) 获取 weight,而后计算 leastCount、totalWeight、sameWeight,最初计算 index

doc

  • least_active

正文完
 0