Golang加权轮询负载均衡的实现

目录

  • 实现加权轮询负载均衡思路
  • 加权轮询负载均衡代码
  • 测试代码

实现加权轮询负载均衡思路
代码实现一个加权负载均衡
  • Weight初始化时对节点约定的权重
  • currentWeight节点临时权重,每轮都会变化
  • effectiveWeight节点有效权重,默认与Weight相同
  • totalWeight所有节点有效权重之和:sum(effectiveWeight)
代码实现一个加权负载均衡
  • currentWeight = currentWeight+effecitveWeight
  • 选中最大的 currentWeight 节点为选中节点
  • currentWeight = currentWeight-totalWeight(4+3+2=9)
【Golang加权轮询负载均衡的实现】所以我们能够 在表格模拟运行情况:

请求次数 请求前currentWelght 选中的节点 请求后currentWelght
1 [serverA=4,serverB=3,serverC=2] serverA [serverA=-1,serverB=6,serverC=4]
2 [serverA=-1,serverB=6,serverC=4] serverB [serverA=3,serverB=0,serverC=6]
3 [serverA=3,serverB=0,serverC=6] serverc [serverA=7,serverB=3,serverC=-1]
4 [serverA=7,serverB=3,serverC=-1] serverA [serverA=2,serverB=6,serverC=1]
5 [serverA=2,serverB=6,serverC=1] serverB [serverA=6,serverB=0,serverC=3]
6 [serverA=6,serverB=0,serverC=3] serverA [serverA=1,serverB=3,serverC=5]
7 [serverA=1,serverB=3,serverC=5] serverc [serverA=5,serverB=6,serverC=-2]


加权轮询负载均衡代码
package load_balanceimport ( "errors" "strconv")type WeightRoundRobinBalance struct { curIndex int rss[]*WeightNode rsw[]int //观察主体 conf LoadBalanceConf}// 配置主题type LoadBalanceConf interface { GetConf() []string WatchConf() UpdateConf(conf []string)}type WeightNode struct { addrstring // 服务器地址 weightint //权重值 currentWeightint //节点当前权重 effectiveWeight int //有效权重}func (r *WeightRoundRobinBalance) Add(params ...string) error { if len(params) != 2 {return errors.New("param len need 2") } parInt, err := strconv.ParseInt(params[1], 10, 64) if err != nil {return err } node := &WeightNode{addr: params[0], weight: int(parInt)} 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]//step 1 统计所有有效权重之和total += w.effectiveWeight//step 2 变更节点临时权重为的节点临时权重+节点有效权重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 "" } //step 5 变更临时权重为 临时权重-有效权重之和 best.currentWeight -= total return best.addr}func (r *WeightRoundRobinBalance) Get(key string) (string, error) { return r.Next(), nil}func (r *WeightRoundRobinBalance) SetConf(conf LoadBalanceConf) { r.conf = conf}


测试代码
package load_balanceimport ( "fmt" "testing")func TestLB(t *testing.T) { rb := &WeightRoundRobinBalance{} rb.Add("127.0.0.1:2003", "4") //0 // rb.Add("127.0.0.1:2004", "3") //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()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next()) fmt.Println(rb.Next())}

测试结果

$ go test
127.0.0.1:2003
127.0.0.1:2005
127.0.0.1:2003
127.0.0.1:2003
127.0.0.1:2005
127.0.0.1:2003
127.0.0.1:2003
127.0.0.1:2005
127.0.0.1:2003
127.0.0.1:2003
127.0.0.1:2005
127.0.0.1:2003
127.0.0.1:2003
127.0.0.1:2005
PASS
okgateway/_test/demo0.080s
## 127.0.0.1:2003 为 127.0.0.1:2005 权重两倍。而从答应结果上看,符合要求
到此这篇关于Golang加权轮询负载均衡的实现的文章就介绍到这了,更多相关Golang加权轮询负载均衡内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    推荐阅读