diff --git a/define/define.go b/define/define.go new file mode 100644 index 0000000..b12236d --- /dev/null +++ b/define/define.go @@ -0,0 +1,21 @@ +// Package define ... +// +// Description : define ... +// +// Author : go_developer@163.com<张德满> +// +// Date : 2021-04-01 5:58 下午 +package define + +// SeverNode 服务器节点的数据结构 +// +// Author : go_developer@163.com<张德满> +// +// Date : 2:46 下午 2021/4/1 +type SeverNode struct { + ID string `json:"id"` // 机器编号 + Host string `json:"host"` // ip + Port int `json:"port"` // 端口 + Weight float64 `json:"weight"` // 权重 + Status int `json:"status"` // 状态 +} diff --git a/define/err.go b/define/err.go new file mode 100644 index 0000000..90d84a8 --- /dev/null +++ b/define/err.go @@ -0,0 +1,53 @@ +// Package define... +// +// Description : define... +// +// Author : go_developer@163.com<张德满> +// +// Date : 2021-04-01 6:38 下午 +package define + +// NewError ... +// +// Author : go_developer@163.com<张德满> +// +// Date : 6:40 下午 2021/4/1 +func NewError(errType string, message string) *Error { + return &Error{ + errType: errType, + message: message, + } +} + +// Error 定义异常 +// +// Author : go_developer@163.com<张德满> +// +// Date : 6:38 下午 2021/4/1 +type Error struct { + errType string + message string +} + +// Error 获取错误信息, 兼容内置 error 类型 +// +// Author : go_developer@163.com<张德满> +// +// Date : 6:39 下午 2021/4/1 +func (e Error) Error() string { + return e.message +} + +// GetErrType 获取错误类型 +// +// Author : go_developer@163.com<张德满> +// +// Date : 6:42 下午 2021/4/1 +func (e Error) GetErrType() string { + return e.errType +} + +const ( + // ErrorTypeNodeListEmpty 服务器节点列表为空 + ErrorTypeNodeListEmpty = "NODE_LIST_EMPTY" +) diff --git a/dispatch/abstract.go b/dispatch/abstract.go new file mode 100644 index 0000000..3199ead --- /dev/null +++ b/dispatch/abstract.go @@ -0,0 +1,20 @@ +// Package dispatch... +// +// Description : dispatch... +// +// Author : go_developer@163.com<张德满> +// +// Date : 2021-04-01 5:53 下午 +package dispatch + +import "github.com/go-developer/balance/define" + +// IDispatch 负载均衡的接口定义 +// +// Author : go_developer@163.com<张德满> +// +// Date : 2:44 下午 2021/4/1 +type IDispatch interface { + // Get 获取一个节点 + Get(nodeList []*define.SeverNode) (string, *define.Error) +} diff --git a/dispatch/rand.go b/dispatch/rand.go new file mode 100644 index 0000000..9458c77 --- /dev/null +++ b/dispatch/rand.go @@ -0,0 +1,45 @@ +// Package dispatch... +// +// Description : dispatch... +// +// Author : go_developer@163.com<张德满> +// +// Date : 2021-04-01 5:58 下午 +package dispatch + +import ( + "fmt" + "math/rand" + + "github.com/go-developer/balance/define" +) + +// NewRand ... +// +// Author : go_developer@163.com<张德满> +// +// Date : 6:51 下午 2021/4/1 +func NewRand() IDispatch { + return &Rand{} +} + +// Rand 随机选择 +// +// Author : go_developer@163.com<张德满> +// +// Date : 6:01 下午 2021/4/1 +type Rand struct { +} + +// Get 获取 host + 端口 +// +// Author : go_developer@163.com<张德满> +// +// Date : 6:01 下午 2021/4/1 +func (r Rand) Get(nodeList []*define.SeverNode) (string, *define.Error) { + if len(nodeList) == 0 { + return "", define.NewError(define.ErrorTypeNodeListEmpty, "服务器可用节点为空") + } + node := nodeList[rand.Intn(len(nodeList))] + return fmt.Sprintf("%s:%d", node.Host, node.Port), nil +} diff --git a/rand_test.go b/rand_test.go new file mode 100644 index 0000000..e02c798 --- /dev/null +++ b/rand_test.go @@ -0,0 +1,41 @@ +// Package dispatch... +// +// Description : dispatch... +// +// Author : go_developer@163.com<张德满> +// +// Date : 2021-04-01 6:48 下午 +package balance + +import ( + "fmt" + "testing" + + "github.com/go-developer/balance/dispatch" + + "github.com/go-developer/balance/define" +) + +// TestRand 测试随机选节点 +// +// Author : go_developer@163.com<张德满> +// +// Date : 6:48 下午 2021/4/1 +func TestRand(t *testing.T) { + result := make(map[string]int) + list := []*define.SeverNode{ + {"127.0.0.1:8080", "127.0.0.1", 8080, 0, 1}, + {"127.0.0.1:8081", "127.0.0.1", 8081, 0, 1}, + {"127.0.0.1:8082", "127.0.0.1", 8082, 0, 1}, + {"127.0.0.1:8083", "127.0.0.1", 8083, 0, 1}, + } + s := NewServer(list, dispatch.NewRand()) + for i := 0; i < 10000; i++ { + node, _ := s.Get() + if _, exist := result[node]; !exist { + result[node] = 0 + } + result[node]++ + } + fmt.Printf("%+v", result) +} diff --git a/abstract.go b/server.go similarity index 60% rename from abstract.go rename to server.go index a965306..3580bc3 100644 --- a/abstract.go +++ b/server.go @@ -8,20 +8,22 @@ package balance import ( + "github.com/go-developer/balance/define" + "github.com/go-developer/balance/dispatch" "github.com/go-developer/gopkg/easylock" ) -// SeverNode 服务器节点的数据结构 +// ... // // Author : go_developer@163.com<张德满> // -// Date : 2:46 下午 2021/4/1 -type SeverNode struct { - ID string `json:"id"` // 机器编号 - Host string `json:"host"` // ip - Port int `json:"port"` // 端口 - Weight float64 `json:"weight"` // 权重 - Status int `json:"status"` // 状态 +// Date : 6:51 下午 2021/4/1 +func NewServer(nodeList []*define.SeverNode, d dispatch.IDispatch) *Server { + return &Server{ + lock: easylock.NewLock(), + NodeList: nodeList, + Balance: d, + } } // Server server 的具体配置 @@ -31,8 +33,8 @@ type SeverNode struct { // Date : 2:59 下午 2021/4/1 type Server struct { lock easylock.EasyLock - NodeList []*SeverNode - Balance IBalance + NodeList []*define.SeverNode + Balance dispatch.IDispatch } // Add 添加一个Server @@ -40,9 +42,11 @@ type Server struct { // Author : go_developer@163.com<张德满> // // Date : 3:00 下午 2021/4/1 -func (s *Server) Add(node *SeverNode) { +func (s *Server) Add(node *define.SeverNode) { _ = s.lock.Lock() - defer s.lock.Unlock() + defer func() { + _ = s.lock.Unlock() + }() s.NodeList = append(s.NodeList, node) } @@ -53,7 +57,9 @@ func (s *Server) Add(node *SeverNode) { // Date : 5:09 下午 2021/4/1 func (s *Server) Remove(nodeID string) { _ = s.lock.Lock() - defer s.lock.Unlock() + defer func() { + _ = s.lock.Unlock() + }() for nodeIndex, item := range s.NodeList { if item.ID == nodeID { s.NodeList = append(s.NodeList[0:nodeIndex], s.NodeList[nodeIndex:]...) @@ -67,17 +73,6 @@ func (s *Server) Remove(nodeID string) { // Author : go_developer@163.com<张德满> // // Date : 5:17 下午 2021/4/1 -func (s *Server) Get() string { - return "" -} - -// IBalance 负载均衡的接口定义 -// -// Author : go_developer@163.com<张德满> -// -// Date : 2:44 下午 2021/4/1 -type IBalance interface { - Get() string - Add(node string) - Remove(node string) +func (s *Server) Get() (string, *define.Error) { + return s.Balance.Get(s.NodeList) }