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

作者:锐玩道 时间:2024-02-01 04:41:57 

目录
  • 实现加权轮询负载均衡思路

  • 加权轮询负载均衡代码

  • 测试代码

实现加权轮询负载均衡思路

代码实现一个加权负载均衡

  • Weight            初始化时对节点约定的权重

  • currentWeight     节点临时权重,每轮都会变化

  • effectiveWeight   节点有效权重,默认与Weight相同

  • totalWeight       所有节点有效权重之和:sum(effectiveWeight)

代码实现一个加权负载均衡

  • currentWeight = currentWeight+effecitveWeight

  • 选中最大的 currentWeight 节点为选中节点

  • currentWeight = currentWeight-totalWeight  (4+3+2=9)

所以我们能够 在表格模拟运行情况:

请求次数请求前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_balance

import (
"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 {
addr            string // 服务器地址
weight          int //权重值
currentWeight   int //节点当前权重
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_balance

import (
"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
ok      gateway/_test/demo      0.080s

## 127.0.0.1:2003 为 127.0.0.1:2005 权重两倍。而从答应结果上看,符合要求

来源:https://juejin.cn/post/6974775746807988232

标签:Golang,加权轮询,负载均衡
0
投稿

猜你喜欢

  • jsp中select的onchange事件用法实例

    2024-04-19 09:58:23
  • layer 刷新某个页面的实现方法

    2024-04-10 10:46:39
  • Apple在Safari 4中抛弃品牌视觉设计

    2009-02-26 13:05:00
  • python pycurl验证basic和digest认证的方法

    2022-12-17 23:01:15
  • Python输出PowerPoint(ppt)文件中全部文字信息的方法

    2023-09-11 15:37:55
  • 微信小程序简单的canvas裁剪图片功能详解

    2023-08-24 07:49:20
  • PYTHON实现SIGN签名的过程解析

    2021-08-09 13:29:05
  • 对Go语言中的context包源码分析

    2024-04-26 17:24:17
  • smarty模板嵌套之include与fetch性能测试

    2024-05-03 15:49:53
  • JS将数字转换成三位逗号分隔的样式(示例代码)

    2024-05-02 16:26:59
  • Python+fuzzywuzzy计算两个字符串之间的相似度

    2021-02-04 16:31:22
  • VsCode搭建Go语言开发环境的配置教程

    2024-05-11 09:09:02
  • vue中的路由传值与重调本路由改变参数

    2024-04-27 16:10:12
  • vue调用高德地图实例代码

    2024-06-07 15:20:47
  • 一文带你探寻Python中的装饰器

    2021-07-11 10:17:59
  • Python使用QQ邮箱发送Email的方法实例

    2021-03-25 11:33:57
  • 将有安全问题的SQL过程删除,比较全面

    2007-08-06 14:46:00
  • 基于plt.title无法显示中文的快速解决

    2023-06-17 10:16:27
  • Google的YSlow——Page Speed(附插件下载)

    2009-09-27 12:40:00
  • JavaScript实现自动变换表格边框颜色

    2024-06-07 15:25:53
  • asp之家 网络编程 m.aspxhome.com