diff --git a/balance/abstract.go b/balance/abstract.go index 1275f69..c8caebc 100644 --- a/balance/abstract.go +++ b/balance/abstract.go @@ -22,7 +22,7 @@ type IBalance interface { // GetServerNode 获取一个服务器节点 GetServerNode(req *http.Request) (*define.ServerNode, error) // AddServerNode 新增一个服务器节点 - AddServerNode(hostIP string, port int) error + AddServerNode(node *define.ServerNode) error // Remove 移除一个节点 Remove(hostIP string, port int, force bool) // GetServerNodeList 获取服务节点列表 diff --git a/balance/base.go b/balance/base.go index 39cc2d3..a9115d2 100644 --- a/balance/base.go +++ b/balance/base.go @@ -65,22 +65,18 @@ func (b *base) RUnlock() { // Author : go_developer@163.com<白茶清欢> // // Date : 10:07 下午 2021/10/20 -func (b *base) AddServerNode(hostIP string, port int) error { - if len(hostIP) == 0 || port <= 0 { +func (b *base) AddServerNode(node *define.ServerNode) error { + if len(node.HostIP) == 0 || node.Port <= 0 { return errors.New("host ip or port is invalid") } b.Lock() defer b.Unlock() for _, item := range b.severList { - if item.HostIP == hostIP && item.Port == port { + if item.HostIP == node.HostIP && item.Port == node.Port { return errors.New("host config is already exist") } } - b.severList = append(b.severList, &define.ServerNode{ - HostIP: hostIP, - Port: port, - Status: define.ServerNodeStatusNormal, - }) + b.severList = append(b.severList, node) return nil } diff --git a/balance/define/node.go b/balance/define/node.go index 9da4418..d6ff5c9 100644 --- a/balance/define/node.go +++ b/balance/define/node.go @@ -13,8 +13,9 @@ package define // // Date : 12:36 下午 2021/10/19 type ServerNode struct { - HostIP string `json:"host_ip"` // 机器IP - Port int `json:"port"` // 机器端口 - Status int `json:"status"` // 机器状态 - Weight int `json:"weight"` // 机器权重 + HostIP string `json:"host_ip"` // 机器IP + Port int `json:"port"` // 机器端口 + Status int `json:"status"` // 机器状态 + Weight float64 `json:"weight"` // 机器权重 + CurrentWeight float64 `json:"current_weight"` // 当前权重 } diff --git a/balance/weight_serverRound_robin.go b/balance/weight_serverRound_robin.go new file mode 100644 index 0000000..0f3aa4b --- /dev/null +++ b/balance/weight_serverRound_robin.go @@ -0,0 +1,114 @@ +// Package balance... +// +// Description : balance... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-11-22 6:58 下午 +package balance + +import ( + "net/http" + "sync" + + "github.com/pkg/errors" + + "git.zhangdeman.cn/zhangdeman/gopkg/balance/define" +) + +// NewWeightServerRoundRobin ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 6:58 下午 2021/11/22 +func NewWeightServerRoundRobin(severList []*define.ServerNode) (IBalance, error) { + if nil == severList || len(severList) == 0 { + return nil, errors.New("sever list is empty") + } + return &WeightServerRoundRobin{ + base: base{ + lock: &sync.RWMutex{}, + severList: severList, + }, + effectiveWeight: 0, + }, nil +} + +// WeightServerRoundRobin 加权轮询 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 6:58 下午 2021/11/22 +type WeightServerRoundRobin struct { + base + effectiveWeight float64 +} + +// GetServerNode ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 7:00 下午 2021/11/22 +func (w *WeightServerRoundRobin) GetServerNode(req *http.Request) (*define.ServerNode, error) { + w.RLock() + defer w.RUnlock() + if len(w.severList) == 0 { + return nil, errors.New("sever list is empty") + } + var expectBackendServer *define.ServerNode + for _, backendServer := range w.severList { + // 给每个后端服务增加自身权重 + backendServer.CurrentWeight += backendServer.Weight + if expectBackendServer == nil { + expectBackendServer = backendServer + } + if backendServer.CurrentWeight > expectBackendServer.CurrentWeight { + expectBackendServer = backendServer + } + } + // 把选择的后端服务权重减掉总权重 + expectBackendServer.CurrentWeight -= w.effectiveWeight + return expectBackendServer, nil +} + +// AddServerNode 新添加一个服务器节点 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:07 下午 2021/10/20 +func (w *WeightServerRoundRobin) AddServerNode(node *define.ServerNode) error { + if len(node.HostIP) == 0 || node.Port <= 0 { + return errors.New("host ip or port is invalid") + } + w.Lock() + defer w.Unlock() + for _, item := range w.severList { + if item.HostIP == node.HostIP && item.Port == node.Port { + return errors.New("host config is already exist") + } + } + w.effectiveWeight += node.Weight + w.severList = append(w.severList, node) + return nil +} + +// Remove 移除一个节点, force = true , 强制删除, force = false 逻辑删除, 设置状态 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:19 下午 2021/10/20 +func (w *WeightServerRoundRobin) Remove(hostIP string, port int, force bool) { + w.Lock() + defer w.Unlock() + tmpServerNode := make([]*define.ServerNode, 0) + for _, item := range w.severList { + if item.HostIP == hostIP && item.Port == port { + if force { + continue + } + item.Status = define.ServerNodeStatusRemove + } + tmpServerNode = append(tmpServerNode, item) + } + w.severList = tmpServerNode +}