sequence

This paper mainly studies the leastactive Veload Balance of Dubo-Go

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{}
}
Copy the code
  • Create leastActiveLoadBalance leastActiveLoadBalance NewLeastActiveLoadBalance method

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] }Copy the code
  • The Select method iterates over invokers, retrieving active information from protocol.getMethodStatus (invoker.geturl (), MethodName()).getActive (). Invocation with GetWeight(Invoker, sameWeight) calculate leastCount, totalWeight, sameWeight; Return Invokers [0] for sameWeight = 1, and if sameWeight is false and totalWeight is greater than 0, iterate over leastWeight and calculate offsetWeight. If sameWeight is less than or equal to 0, Returns Invokers [index], otherwise returns Invokers [index] by leastIndexes[rand.Intn(leastCount)]

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
}
Copy the code
  • The GetWeight method gets the weight from urL.getmethodParamint64 (Invocation.methodName (), constant.weight_key, constant.default_weight), If the weight is greater than 0, calculate warmUp and recalculate the weight value

summary

LeastActiveLoadBalance create leastActiveLoadBalance NewLeastActiveLoadBalance method; The Select method iterates over invokers, retrieving active information from protocol.getMethodStatus (invoker.geturl (), MethodName()).getActive (). The invocation GetWeight(invoker, invocation) is used to derive weight, then calculate leastCount, totalWeight, sameWeight, and index

doc

  • least_active