专栏首页码匠的流水账聊聊dubbo-go的leastActiveLoadBalance
原创

聊聊dubbo-go的leastActiveLoadBalance

本文主要研究一下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

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊dubbo-go的leastActiveLoadBalance

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

    codecraft
  • 聊聊eureka的ZoneAffinityServerListFilter

    本文主要研究一下eureka的ZoneAffinityServerListFilter

    codecraft
  • 聊聊nacos ServiceManager的registerInstance

    本文主要研究一下nacos ServiceManager的registerInstance

    codecraft
  • 聊聊dubbo-go的leastActiveLoadBalance

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

    codecraft
  • 【思维导图】深入理解HTTPS原理、过程

    我们经常会遇到页面被运营商插入小广告这种事情(数据被篡改),可想而知,HTTP是有多么不安全。 如何做到的? 答:只需要设定相应的DNS,做一个中间人攻击,再...

    java思维导图
  • 聊聊eureka的ZoneAffinityServerListFilter

    本文主要研究一下eureka的ZoneAffinityServerListFilter

    codecraft
  • JavaScript 究竟是怎样执行的?

    JS 引擎 — 一个读取代码并运行的引擎,没有单一的“JS 引擎”;每个浏览器都有自己的引擎,如谷歌有 V。

    Fundebug
  • 搞懂JavaScript引擎运行原理

    JS引擎 — 一个读取代码并运行的引擎,没有单一的“JS引擎”;,每个浏览器都有自己的引擎,如谷歌有V。

    前端小智@大迁世界
  • 诺基亚发布VR摄像机,用它砸核桃会肉痛!

    VRPinea
  • 1724: [Usaco2006 Nov]Fence Repair 切割木板

    1724: [Usaco2006 Nov]Fence Repair 切割木板 Time Limit: 5 Sec  Memory Limit: 64 MB Su...

    HansBug

扫码关注云+社区

领取腾讯云代金券