增加平滑给予权重负载的调度策略实现
This commit is contained in:
parent
48c8c1652d
commit
7c6c3b1bfe
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,9 @@ import (
|
|||||||
|
|
||||||
// IServer 服务节点集合的接口约束
|
// IServer 服务节点集合的接口约束
|
||||||
type IServer interface {
|
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) // 修改负载均衡策略
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,14 @@ package define
|
|||||||
//
|
//
|
||||||
// Date : 2:46 下午 2021/4/1
|
// Date : 2:46 下午 2021/4/1
|
||||||
type SeverNode struct {
|
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"` // 权重
|
||||||
Status int `json:"status"` // 状态
|
CurrentWeight int64 `json:"current_weight"` // 当前权重
|
||||||
Count uint64 `json:"count"` // 节点访问次数, 用于实现最小访问次数的策略
|
EffectiveWeight int64 `json:"effective_weight"` // 有效权重
|
||||||
CostTime uint64 `json:"cost_time"` // 节点访问耗时, 用于实现最小访问耗时的策略
|
Status int `json:"status"` // 状态
|
||||||
FailureCount uint64 `json:"failure_count"` // 节点访问失败次数, 用于实现最小访问失败次数的策略
|
Count uint64 `json:"count"` // 节点访问次数, 用于实现最小访问次数的策略
|
||||||
|
CostTime uint64 `json:"cost_time"` // 节点访问耗时, 用于实现最小访问耗时的策略
|
||||||
|
FailureCount uint64 `json:"failure_count"` // 节点访问失败次数, 用于实现最小访问失败次数的策略
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
42
implement/weight_round_robin.go
Normal file
42
implement/weight_round_robin.go
Normal 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
|
||||||
|
}
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user