四种负载均衡策略

(一) 加权负轮询负载均衡

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个

在这里插入图片描述