增加平滑给予权重负载的调度策略实现

This commit is contained in:
白茶清欢 2025-05-24 12:01:22 +08:00
parent 48c8c1652d
commit 7c6c3b1bfe
7 changed files with 70 additions and 32 deletions

View File

@ -19,5 +19,5 @@ import (
// Date : 2:44 下午 2021/4/1 // Date : 2:44 下午 2021/4/1
type IBalance interface { type IBalance interface {
// Get 获取一个节点 // Get 获取一个节点
Get(nodeList []*define.SeverNode) (string, exception.IException) Get(nodeList []*define.SeverNode) (*define.SeverNode, exception.IException)
} }

View File

@ -17,6 +17,6 @@ type IServer interface {
Add(node *define.SeverNode) // 在集群中添加一个节点 Add(node *define.SeverNode) // 在集群中添加一个节点
Modify(node *define.SeverNode) // 修改集群中一个节点的信息 Modify(node *define.SeverNode) // 修改集群中一个节点的信息
Remove(nodeID string) // 在集群中移除一个节点 Remove(nodeID string) // 在集群中移除一个节点
Get() (string, exception.IException) // 获取一个访问节点 Get() (*define.SeverNode, exception.IException) // 获取一个访问节点
ChangeBalance(d IBalance) // 修改负载均衡策略 ChangeBalance(d IBalance) // 修改负载均衡策略
} }

View File

@ -16,7 +16,9 @@ type SeverNode struct {
ID string `json:"id"` // 机器编号 ID string `json:"id"` // 机器编号
Host string `json:"host"` // ip Host string `json:"host"` // ip
Port int `json:"port"` // 端口 Port int `json:"port"` // 端口
Weight float64 `json:"weight"` // 权重 Weight int64 `json:"weight"` // 权重
CurrentWeight int64 `json:"current_weight"` // 当前权重
EffectiveWeight int64 `json:"effective_weight"` // 有效权重
Status int `json:"status"` // 状态 Status int `json:"status"` // 状态
Count uint64 `json:"count"` // 节点访问次数, 用于实现最小访问次数的策略 Count uint64 `json:"count"` // 节点访问次数, 用于实现最小访问次数的策略
CostTime uint64 `json:"cost_time"` // 节点访问耗时, 用于实现最小访问耗时的策略 CostTime uint64 `json:"cost_time"` // 节点访问耗时, 用于实现最小访问耗时的策略

View File

@ -1,4 +1,4 @@
// Package dispatch... // Package implement ...
// //
// Description : dispatch... // Description : dispatch...
// //
@ -8,7 +8,6 @@
package implement package implement
import ( import (
"fmt"
"git.zhangdeman.cn/gateway/balance/abstract" "git.zhangdeman.cn/gateway/balance/abstract"
"git.zhangdeman.cn/zhangdeman/exception" "git.zhangdeman.cn/zhangdeman/exception"
"math/rand" "math/rand"
@ -38,10 +37,10 @@ type Rand struct {
// Author : go_developer@163.com<张德满> // Author : go_developer@163.com<张德满>
// //
// Date : 6:01 下午 2021/4/1 // Date : 6:01 下午 2021/4/1
func (r Rand) Get(nodeList []*define.SeverNode) (string, exception.IException) { func (r Rand) Get(nodeList []*define.SeverNode) (*define.SeverNode, exception.IException) {
if len(nodeList) == 0 { if len(nodeList) == 0 {
return "", exception.New(define.ErrorTypeNodeListEmpty, nil, "服务器可用节点为空") return nil, exception.New(define.ErrorTypeNodeListEmpty, nil, "服务器可用节点为空")
} }
node := nodeList[rand.Intn(len(nodeList))] node := nodeList[rand.Intn(len(nodeList))]
return fmt.Sprintf("%s:%d", node.Host, node.Port), nil return node, nil
} }

View File

@ -8,12 +8,10 @@
package implement package implement
import ( import (
"fmt"
"git.zhangdeman.cn/gateway/balance/abstract" "git.zhangdeman.cn/gateway/balance/abstract"
"git.zhangdeman.cn/zhangdeman/exception" "git.zhangdeman.cn/zhangdeman/exception"
"git.zhangdeman.cn/gateway/balance/define" "git.zhangdeman.cn/gateway/balance/define"
"git.zhangdeman.cn/zhangdeman/easylock"
) )
// NewRoundRobin 轮询调度 // NewRoundRobin 轮询调度
@ -23,7 +21,6 @@ import (
// Date : 8:07 下午 2021/4/1 // Date : 8:07 下午 2021/4/1
func NewRoundRobin() abstract.IBalance { func NewRoundRobin() abstract.IBalance {
return &RoundRobin{ return &RoundRobin{
lock: easylock.NewLock(),
nextNodeIndex: 0, nextNodeIndex: 0,
} }
} }
@ -34,7 +31,6 @@ func NewRoundRobin() abstract.IBalance {
// //
// Date : 8:06 下午 2021/4/1 // Date : 8:06 下午 2021/4/1
type RoundRobin struct { type RoundRobin struct {
lock easylock.EasyLock
nextNodeIndex int nextNodeIndex int
} }
@ -43,19 +39,14 @@ type RoundRobin struct {
// Author : go_developer@163.com<张德满> // Author : go_developer@163.com<张德满>
// //
// Date : 8:05 下午 2021/4/1 // Date : 8:05 下午 2021/4/1
func (r *RoundRobin) Get(nodeList []*define.SeverNode) (string, exception.IException) { func (r *RoundRobin) Get(nodeList []*define.SeverNode) (*define.SeverNode, exception.IException) {
if len(nodeList) == 0 { if len(nodeList) == 0 {
return "", exception.New(define.ErrorTypeNodeListEmpty, nil, "服务器可用节点为空") return nil, exception.New(define.ErrorTypeNodeListEmpty, nil, "服务器可用节点为空")
} }
_ = r.lock.Lock()
defer func() {
_ = r.lock.Unlock()
}()
if r.nextNodeIndex >= len(nodeList) { if r.nextNodeIndex >= len(nodeList) {
// 记录过索引之后, 在下次访问之前, 可能移除了某些节点, 所以要检测越界 // 记录过索引之后, 在下次访问之前, 可能移除了某些节点, 所以要检测越界
r.nextNodeIndex = len(nodeList) - 1 r.nextNodeIndex = len(nodeList) - 1
} }
node := fmt.Sprintf("%s:%d", nodeList[r.nextNodeIndex].Host, nodeList[r.nextNodeIndex].Port)
r.nextNodeIndex = (r.nextNodeIndex + 1) % len(nodeList) r.nextNodeIndex = (r.nextNodeIndex + 1) % len(nodeList)
return node, nil return nodeList[r.nextNodeIndex], nil
} }

View File

@ -0,0 +1,42 @@
// Package implement ...
//
// Description : implement ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-05-23 23:24
package implement
import (
"git.zhangdeman.cn/gateway/balance/abstract"
"git.zhangdeman.cn/gateway/balance/define"
"git.zhangdeman.cn/zhangdeman/exception"
)
func NewWeightRoundRobin() abstract.IBalance {
return &WeightRoundRobin{}
}
// WeightRoundRobin 加权轮询选择机器
type WeightRoundRobin struct {
}
func (w *WeightRoundRobin) Get(nodeList []*define.SeverNode) (*define.SeverNode, exception.IException) {
totalWeight := int64(0)
var selectedNode *define.SeverNode
// 计算总权重
for _, node := range nodeList {
node.CurrentWeight = node.CurrentWeight + node.EffectiveWeight // 每个节点的当前权重
totalWeight += node.Weight
if nil == selectedNode {
selectedNode = node
} else {
if node.CurrentWeight > selectedNode.CurrentWeight {
selectedNode = node
}
}
}
// 当前选中节点权重重置
selectedNode.CurrentWeight = selectedNode.CurrentWeight - totalWeight
return selectedNode, nil
}

View File

@ -49,6 +49,8 @@ func (s *Server) Add(node *define.SeverNode) {
defer func() { defer func() {
s.lock.Unlock() s.lock.Unlock()
}() }()
node.EffectiveWeight = node.Weight
node.CurrentWeight = 0
s.NodeList = append(s.NodeList, node) s.NodeList = append(s.NodeList, node)
} }
@ -75,7 +77,7 @@ func (s *Server) Remove(nodeID string) {
// Author : go_developer@163.com<张德满> // Author : go_developer@163.com<张德满>
// //
// Date : 5:17 下午 2021/4/1 // Date : 5:17 下午 2021/4/1
func (s *Server) Get() (string, exception.IException) { func (s *Server) Get() (*define.SeverNode, exception.IException) {
s.lock.RLock() s.lock.RLock()
defer func() { defer func() {
s.lock.RUnlock() s.lock.RUnlock()
@ -91,6 +93,8 @@ func (s *Server) Modify(node *define.SeverNode) {
defer func() { defer func() {
s.lock.RUnlock() s.lock.RUnlock()
}() }()
node.EffectiveWeight = node.Weight
node.CurrentWeight = 0
findExistNode := false findExistNode := false
for nodeIndex, item := range s.NodeList { for nodeIndex, item := range s.NodeList {
if item.ID == node.ID { if item.ID == node.ID {