四种负载均衡策略
(一) 加权负轮询负载均衡
Weight: 初始化时对节点约定的权重
currentWeight: 节点临时权重 每轮都会发生变化
effectiveWeight:节点有效权重,默认玉weight 相同
type WeightRoundRobinBalance struct {
curIndex int
rss []*WeightNode
rsw []int
}
type WeightNode struct {
addr string
weight int //权重
currentWeight int //节点当前权重
effectiveWeight int //有效权重
}
不考虑节点故障
有效权重等于 权重 第一次节点当前权重也等于权重
currentweight = currentweight + effectiveweight
选中最大的currentweight 节点为选中节点
选中后的currentweight 要做处理
currentWeight =currentWeight-totalweight -1= 8-(4+3+2)
func (r *WeightRoundRobinBalance) Add(params ...string)error {
if len(params)!=2 {
return errors.New("params must 2")
}
parseInt ,err:=strconv.ParseInt(params[1],10,64)
if err != nil {
return err
}
node:=&WeightNode{addr: params[0],weight: int(parseInt)}
node.effectiveWeight=node.weight
r.rss=append(r.rss,node)
return nil
}
func (r *WeightRoundRobinBalance) Next()string{
total:=0
var best *WeightNode
for i := 0; i <len(r.rss) ; i++ {
w:=r.rss[i]
// step1 统计所有有效权重之和
total =total+w.effectiveWeight
// step2 变更节点临时权重为:节点临时权重+节点有效权重
w.currentWeight +=w.effectiveWeight
// step 3 有效权重默认与权重相同,通讯异常时-1, 通讯成功+1,直到恢复到weight大小
if w.effectiveWeight <w.weight{
w.effectiveWeight++
}
//step 4 选择最大临时权重点节点
if best == nil || w.currentWeight > best.currentWeight {
best = w
}
}
if best == nil {
return ""
}
best.currentWeight -=total
return best.addr
}
设置测试用例
func TestB(t *testing.T) {
rb := &WeightRoundRobinBalance{}
rb.Add("127.0.0.1:2003", "4") //0
rb.Add("127.0.0.1:2004", "4") //1
rb.Add("127.0.0.1:2005", "2") //2
fmt.Println(rb.Next())
fmt.Println(rb.Next())
fmt.Println(rb.Next())
fmt.Println(rb.Next())
fmt.Println(rb.Next())
fmt.Println(rb.Next())
fmt.Println(rb.Next())
fmt.Println(rb.Next())
fmt.Println(rb.Next())
fmt.Println(rb.Next())
}
测试结果如下图所示 2003 和2004这两个节点负载为4个 2005 节点负载为2个