聊聊dubbo-go的leastActiveLoadBalance
时间:2022-07-23
本文章向大家介绍聊聊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
- least_active
- 用粒子群优化算法求解旅行商问题
- 使用CNN(LSTM架构)进行序列预测基于TensorFlow
- 【独家】周志华教授gcForest(多粒度级联森林)算法预测股指期货涨跌
- 如何利用SOTER,1个版本内完成指纹支付开发?
- Rafy 框架 - 大批量导入实体
- Rafy 框架 - 执行SQL或存储过程
- 关于activitygroup过时,用frament替换操作
- Rafy 框架 - 为数据库生成注释
- CNN预测股票走势基于Tensorflow(思路+程序)
- 路径查找器AI
- android推荐使用dialogFrament而不是alertDialog
- 自定义圆角和园边的实现
- Rafy 中的 Linq 查询支持(根据聚合子条件查询聚合父)
- 应用潜在语义分析技术将文档进行3D可视化
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Centos7.3服务器搭建LNMP环境的方法
- Linux中解除端口占用的方法
- ubuntu服务器环境下安装python的方法
- 带你入门Linux中size命令的6个例子
- 详解CentOS重启后resolv.conf被重置的解决方案
- scRNA-seq Clustering quality control(二)
- ubuntu环境下安装memcache及启动的方法
- Linux下批量修改服务器用户密码方法步骤
- Linux 常用文本处理命令和vim文本编辑器
- centos7利用yum安装lnmp的教程(linux+nginx+php7.1+mysql5.7)
- linux根据进程号PID查找启动程序的全路径
- linux服务器安装PHP扩展zip,zlib方法
- Lamp环境下设置绑定apache域名的方法分析
- Linux杀不死的进程之CPU使用率700%解决方法
- 解读Linux下ip命令展示的网络连接信息