Golang加权轮询负载均衡的实现
作者:锐玩道 发布时间:2024-02-01 04:41:57
标签:Golang,加权轮询,负载均衡
目录
实现加权轮询负载均衡思路
加权轮询负载均衡代码
测试代码
实现加权轮询负载均衡思路
代码实现一个加权负载均衡
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


猜你喜欢
- 前言你是否曾经想将某张照片中的人物抠出来,然后拼接到其他图片上去,从而可以即使你在天涯海角,我也可以到此一游?专业点的人使用 PhotoSh
- golang的defer优雅又简洁, 是golang的亮点之一。defer在声明时不会立即执行,而是在函数return后,再按照先进后出的原
- python:如何将excel文件转化成CSV格式import pandas as pddata = pd.read_excel('
- 1.颜色空间转换使用cv2.cvtColor(input_image ,flag),flag为转换类型常用的转换类型有:BGR和灰度图的转换
- 第一次使用python写程序,确实比C/C++之类方便许多。既然这个抽奖的数据不大,对效率要求并不高,所以采用python写,更加简洁、清晰
- tkinter下载进度条利用python爬取网站数据进行下载时,显示下载进度# 设置下载进度条tk.Label(window, text=&
- 前言聚簇索引就是innodb默认创建的基于主键的索引结构,而且表里的数据就是直接放在聚簇索引里,作为叶节点的数据页:基于主键的数据搜索:从聚
- 安装MySQL ODBC驱动官方说法:MySQL ODBC 驱动程序负责在开放式数据库连接 API (ODBC API) 的帮助下访问 My
- python中捕获键盘操作一共有两种方法第一种方法:使用pygame中event方法使用方式如下:使用键盘右键为例if event.type
- 前言sklearn是python的重要机器学习库,其中封装了大量的机器学习算法,如:分类、回归、降维以及聚类;还包含了监督学习、非监督学习、
- 1.selenum:三方库。可以实现让浏览器完成自动化的操作。2.环境搭建2.1 安装:pip install selenium2.2 获取
- 在进行数据分析、数据建模时,我们首先要做的就是对数据进行处理,提取我们需要的信息。下面为大家介绍一些groupby的用法,以便能够更加方便地
- 问题详情:偶然在根目录创建文件夹的时候,突然显示错误,当时很惊讶,以前没遇见过这样的问题。当时界面是这样的。 用了一个 cd / 命令从用户
- 前言:事务(Transaction)是一组SQL组成的执行单元(Unit),是数据库并发控制和恢复回滚的基本单位。一个事务中可能包含多个SQ
- 近日,有朋友一直打听flash连结服务器相关的知识,搞得我忧心重重,重点是自己也忘记了,大部分Flash的相关开发都是两年前的事,而且fla
- 一般要用到递归,就要判断对象是否和父类型是否一样这里演示简单的对象递归,还有数组递归类似。var obj = { a:{w:1,y:2,x:
- Windows 10家庭中文版,Python 3.6.4,stomp.py 4.1.21ActiveMQ支持Python访问,提供了基于ST
- 一、前言刚开始学Python的小伙伴可能会觉得每次写Python打开Cmd或者idle有点烦躁,没有代码补全也没有格式提示等。所以直接上手了
- 《页面表达常用方式》是整个“web交互设计方法”中的一部分:设计师在设计页面时,应该在页面上建立许多视觉层次,引导用户的视觉焦点。把用户的注
- 大多数使用 WordPress 搭建的网站,其后台都是 MySQL 数据库,经常我们需要定制 WordPress 的功能,这里我们列表 10