Compare commits
	
		
			12 Commits
		
	
	
		
			bfe2ec5b18
			...
			feature/ec
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 391e47fe33 | |||
| fa426ae90c | |||
| 39e3cdef91 | |||
| ad8c3dc47d | |||
| 42282e2001 | |||
| 376f3dfb23 | |||
| 275e52a108 | |||
| ffccdeffd4 | |||
| 30059c0341 | |||
| cf210a4514 | |||
| a9a4287650 | |||
| affaca969e | 
							
								
								
									
										30
									
								
								balance/abstract.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								balance/abstract.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
			
		||||
// Package balance...
 | 
			
		||||
//
 | 
			
		||||
// Description : balance...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-22 4:45 下午
 | 
			
		||||
package balance
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"git.zhangdeman.cn/zhangdeman/gopkg/balance/define"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// IBalance 负载算法接口约束
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 4:45 下午 2021/11/22
 | 
			
		||||
type IBalance interface {
 | 
			
		||||
	// GetServerNode 获取一个服务器节点
 | 
			
		||||
	GetServerNode(req *http.Request) (*define.ServerNode, error)
 | 
			
		||||
	// AddServerNode 新增一个服务器节点
 | 
			
		||||
	AddServerNode(node *define.ServerNode) error
 | 
			
		||||
	// Remove 移除一个节点
 | 
			
		||||
	Remove(hostIP string, port int, force bool)
 | 
			
		||||
	// GetServerNodeList 获取服务节点列表
 | 
			
		||||
	GetServerNodeList() []*define.ServerNode
 | 
			
		||||
}
 | 
			
		||||
@ -7,7 +7,12 @@
 | 
			
		||||
// Date : 2021-10-19 2:26 下午
 | 
			
		||||
package balance
 | 
			
		||||
 | 
			
		||||
import "sync"
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"git.zhangdeman.cn/zhangdeman/gopkg/balance/define"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// base ...
 | 
			
		||||
//
 | 
			
		||||
@ -15,7 +20,8 @@ import "sync"
 | 
			
		||||
//
 | 
			
		||||
// Date : 2:26 下午 2021/10/19
 | 
			
		||||
type base struct {
 | 
			
		||||
	lock *sync.RWMutex
 | 
			
		||||
	lock      *sync.RWMutex
 | 
			
		||||
	severList []*define.ServerNode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Lock ...
 | 
			
		||||
@ -53,3 +59,53 @@ func (b *base) RLock() {
 | 
			
		||||
func (b *base) RUnlock() {
 | 
			
		||||
	b.lock.RUnlock()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddServerNode 新添加一个服务器节点
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 10:07 下午 2021/10/20
 | 
			
		||||
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 == node.HostIP && item.Port == node.Port {
 | 
			
		||||
			return errors.New("host config is already exist")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	b.severList = append(b.severList, node)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Remove 移除一个节点, force = true , 强制删除, force = false 逻辑删除, 设置状态
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 10:19 下午 2021/10/20
 | 
			
		||||
func (b *base) Remove(hostIP string, port int, force bool) {
 | 
			
		||||
	b.Lock()
 | 
			
		||||
	defer b.Unlock()
 | 
			
		||||
	tmpServerNode := make([]*define.ServerNode, 0)
 | 
			
		||||
	for _, item := range b.severList {
 | 
			
		||||
		if item.HostIP == hostIP && item.Port == port {
 | 
			
		||||
			if force {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			item.Status = define.ServerNodeStatusRemove
 | 
			
		||||
		}
 | 
			
		||||
		tmpServerNode = append(tmpServerNode, item)
 | 
			
		||||
	}
 | 
			
		||||
	b.severList = tmpServerNode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetServerNodeList 获取服务器节点
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 10:33 下午 2021/10/20
 | 
			
		||||
func (b *base) GetServerNodeList() []*define.ServerNode {
 | 
			
		||||
	return b.severList
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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"` // 当前权重
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								balance/ip_hash.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								balance/ip_hash.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,62 @@
 | 
			
		||||
// Package balance...
 | 
			
		||||
//
 | 
			
		||||
// Description : balance...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-22 4:39 下午
 | 
			
		||||
package balance
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"git.zhangdeman.cn/zhangdeman/gopkg/util"
 | 
			
		||||
 | 
			
		||||
	"github.com/pkg/errors"
 | 
			
		||||
 | 
			
		||||
	"git.zhangdeman.cn/zhangdeman/gopkg/balance/define"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NewIPHash ip hash 负载均衡
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 4:53 下午 2021/11/22
 | 
			
		||||
func NewIPHash(severList []*define.ServerNode) (IBalance, error) {
 | 
			
		||||
	if nil == severList || len(severList) == 0 {
 | 
			
		||||
		return nil, errors.New("sever list is empty")
 | 
			
		||||
	}
 | 
			
		||||
	return &IPHash{
 | 
			
		||||
		base: base{
 | 
			
		||||
			lock:      &sync.RWMutex{},
 | 
			
		||||
			severList: severList,
 | 
			
		||||
		},
 | 
			
		||||
		serverList: severList,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IPHash ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 4:57 下午 2021/11/22
 | 
			
		||||
type IPHash struct {
 | 
			
		||||
	base
 | 
			
		||||
	serverList []*define.ServerNode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetServerNode ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 4:53 下午 2021/11/22
 | 
			
		||||
func (ih *IPHash) GetServerNode(req *http.Request) (*define.ServerNode, error) {
 | 
			
		||||
	clintIPHashID := util.GetHashID(util.GetRemoteIp(req))
 | 
			
		||||
	ih.RLock()
 | 
			
		||||
	defer ih.RUnlock()
 | 
			
		||||
	if len(ih.serverList) == 0 {
 | 
			
		||||
		return nil, errors.New("sever list is empty")
 | 
			
		||||
	}
 | 
			
		||||
	return ih.serverList[int(clintIPHashID%uint64(len(ih.serverList)))], nil
 | 
			
		||||
}
 | 
			
		||||
@ -8,6 +8,7 @@
 | 
			
		||||
package balance
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"git.zhangdeman.cn/zhangdeman/gopkg/balance/define"
 | 
			
		||||
@ -19,15 +20,15 @@ import (
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 12:40 下午 2021/10/19
 | 
			
		||||
func NewPoll(serverList []*define.ServerNode) (*Poll, error) {
 | 
			
		||||
func NewPoll(serverList []*define.ServerNode) (IBalance, error) {
 | 
			
		||||
	if nil == serverList || len(serverList) == 0 {
 | 
			
		||||
		return nil, errors.New("server list is empty")
 | 
			
		||||
	}
 | 
			
		||||
	return &Poll{
 | 
			
		||||
		base: base{
 | 
			
		||||
			lock: &sync.RWMutex{},
 | 
			
		||||
			lock:      &sync.RWMutex{},
 | 
			
		||||
			severList: serverList,
 | 
			
		||||
		},
 | 
			
		||||
		serverList:         serverList,
 | 
			
		||||
		currentServerIndex: 0,
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
@ -39,7 +40,6 @@ func NewPoll(serverList []*define.ServerNode) (*Poll, error) {
 | 
			
		||||
// Date : 12:41 下午 2021/10/19
 | 
			
		||||
type Poll struct {
 | 
			
		||||
	base
 | 
			
		||||
	serverList         []*define.ServerNode
 | 
			
		||||
	currentServerIndex int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -48,21 +48,18 @@ type Poll struct {
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 12:43 下午 2021/10/19
 | 
			
		||||
func (p *Poll) GetServerNode() (*define.ServerNode, error) {
 | 
			
		||||
	if len(p.serverList) == 0 {
 | 
			
		||||
		return nil, errors.New("server list is empty")
 | 
			
		||||
	}
 | 
			
		||||
	p.Lock()
 | 
			
		||||
	defer p.Unlock()
 | 
			
		||||
func (p *Poll) GetServerNode(req *http.Request) (*define.ServerNode, error) {
 | 
			
		||||
	p.RLock()
 | 
			
		||||
	defer p.RUnlock()
 | 
			
		||||
	var (
 | 
			
		||||
		serverNode *define.ServerNode
 | 
			
		||||
	)
 | 
			
		||||
	// 循环次数
 | 
			
		||||
	loopTimes := 0
 | 
			
		||||
	for loopTimes < len(p.serverList) {
 | 
			
		||||
	for loopTimes < len(p.severList) {
 | 
			
		||||
		loopTimes++
 | 
			
		||||
		p.currentServerIndex = (p.currentServerIndex + 1) % len(p.serverList)
 | 
			
		||||
		if serverNode = p.serverList[p.currentServerIndex]; serverNode.Status != define.ServerNodeStatusNormal {
 | 
			
		||||
		p.currentServerIndex = (p.currentServerIndex + 1) % len(p.severList)
 | 
			
		||||
		if serverNode = p.severList[p.currentServerIndex]; serverNode.Status != define.ServerNodeStatusNormal {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		break
 | 
			
		||||
@ -74,57 +71,3 @@ func (p *Poll) GetServerNode() (*define.ServerNode, error) {
 | 
			
		||||
 | 
			
		||||
	return serverNode, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddServerNode 新添加一个服务器节点
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 10:07 下午 2021/10/20
 | 
			
		||||
func (p *Poll) AddServerNode(hostIP string, port int) error {
 | 
			
		||||
	if len(hostIP) == 0 || port <= 0 {
 | 
			
		||||
		return errors.New("host ip or port is invalid")
 | 
			
		||||
	}
 | 
			
		||||
	p.Lock()
 | 
			
		||||
	defer p.Unlock()
 | 
			
		||||
	for _, item := range p.serverList {
 | 
			
		||||
		if item.HostIP == hostIP && item.Port == port {
 | 
			
		||||
			return errors.New("host config is already exist")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	p.serverList = append(p.serverList, &define.ServerNode{
 | 
			
		||||
		HostIP: hostIP,
 | 
			
		||||
		Port:   port,
 | 
			
		||||
		Status: define.ServerNodeStatusNormal,
 | 
			
		||||
	})
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Remove 移除一个节点, force = true , 强制删除, force = false 逻辑删除, 设置状态
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 10:19 下午 2021/10/20
 | 
			
		||||
func (p *Poll) Remove(hostIP string, port int, force bool) {
 | 
			
		||||
	p.Lock()
 | 
			
		||||
	defer p.Unlock()
 | 
			
		||||
	tmpServerNode := make([]*define.ServerNode, 0)
 | 
			
		||||
	for _, item := range p.serverList {
 | 
			
		||||
		if item.HostIP == hostIP && item.Port == port {
 | 
			
		||||
			if force {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			item.Status = define.ServerNodeStatusRemove
 | 
			
		||||
		}
 | 
			
		||||
		tmpServerNode = append(tmpServerNode, item)
 | 
			
		||||
	}
 | 
			
		||||
	p.serverList = tmpServerNode
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetServerNodeList 获取服务器节点
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 10:33 下午 2021/10/20
 | 
			
		||||
func (p *Poll) GetServerNodeList() []*define.ServerNode {
 | 
			
		||||
	return p.serverList
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										59
									
								
								balance/random.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								balance/random.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
			
		||||
// Package balance...
 | 
			
		||||
//
 | 
			
		||||
// Description : balance...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-22 6:27 下午
 | 
			
		||||
package balance
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"sync"
 | 
			
		||||
 | 
			
		||||
	"git.zhangdeman.cn/zhangdeman/gopkg/util"
 | 
			
		||||
 | 
			
		||||
	"git.zhangdeman.cn/zhangdeman/gopkg/balance/define"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// NewRandom ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 6:29 下午 2021/11/22
 | 
			
		||||
func NewRandom(severList []*define.ServerNode) (IBalance, error) {
 | 
			
		||||
	if nil == severList || len(severList) == 0 {
 | 
			
		||||
		return nil, errors.New("sever list is empty")
 | 
			
		||||
	}
 | 
			
		||||
	return &Random{
 | 
			
		||||
		base{
 | 
			
		||||
			lock:      &sync.RWMutex{},
 | 
			
		||||
			severList: make([]*define.ServerNode, 0),
 | 
			
		||||
		},
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Random 随机负载均衡
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 6:27 下午 2021/11/22
 | 
			
		||||
type Random struct {
 | 
			
		||||
	base
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetServerNode ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 6:31 下午 2021/11/22
 | 
			
		||||
func (r *Random) GetServerNode(req *http.Request) (*define.ServerNode, error) {
 | 
			
		||||
	r.RLock()
 | 
			
		||||
	defer r.RUnlock()
 | 
			
		||||
	if len(r.severList) == 0 {
 | 
			
		||||
		return nil, errors.New("sever list is empty")
 | 
			
		||||
	}
 | 
			
		||||
	randomID := util.GetHashID(util.GenRandomString("", 128)) % uint64(len(r.severList))
 | 
			
		||||
	return r.severList[int(randomID)], nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										114
									
								
								balance/weight_serverRound_robin.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								balance/weight_serverRound_robin.go
									
									
									
									
									
										Normal file
									
								
							@ -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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										103
									
								
								consistent_hash/consistent.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								consistent_hash/consistent.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,103 @@
 | 
			
		||||
// Package consistent_hash...
 | 
			
		||||
//
 | 
			
		||||
// Description : consistent_hash...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-21 4:57 下午
 | 
			
		||||
package consistent_hash
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// New 获取实例
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:03 下午 2021/11/21
 | 
			
		||||
func New(replicas int, fn HashFunc) *Consistent {
 | 
			
		||||
	if nil == fn {
 | 
			
		||||
		fn = DefaultHashFunc
 | 
			
		||||
	}
 | 
			
		||||
	return &Consistent{
 | 
			
		||||
		hashFunc: fn,
 | 
			
		||||
		replicas: replicas,
 | 
			
		||||
		keys:     make([]int, 0),
 | 
			
		||||
		hashMap:  make(map[int]string),
 | 
			
		||||
		lock:     &sync.RWMutex{},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Consistent ...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:00 下午 2021/11/21
 | 
			
		||||
type Consistent struct {
 | 
			
		||||
	hashFunc HashFunc       // 哈希函数
 | 
			
		||||
	replicas int            // 虚拟的数量
 | 
			
		||||
	keys     []int          // 哈希环
 | 
			
		||||
	hashMap  map[int]string // 虚拟节点与真实节点的映射表
 | 
			
		||||
	lock     *sync.RWMutex  // 锁
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Add 添加节点
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:10 下午 2021/11/21
 | 
			
		||||
func (c *Consistent) Add(keyList ...string) {
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
	for _, key := range keyList {
 | 
			
		||||
		for i := 0; i < c.replicas; i++ {
 | 
			
		||||
			hash := int(c.hashFunc([]byte(strconv.Itoa(i) + key)))
 | 
			
		||||
			c.keys = append(c.keys, hash)
 | 
			
		||||
			c.hashMap[hash] = key
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// 哈希值排序
 | 
			
		||||
	sort.Ints(c.keys)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get 获取节点
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:16 下午 2021/11/21
 | 
			
		||||
func (c *Consistent) Get(key string) string {
 | 
			
		||||
	c.lock.RLock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
	if len(c.keys) == 0 {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
	hash := int(c.hashFunc([]byte(key)))
 | 
			
		||||
	// 查找节点索引
 | 
			
		||||
	idx := sort.Search(len(c.keys), func(i int) bool {
 | 
			
		||||
		return c.keys[i] >= hash
 | 
			
		||||
	})
 | 
			
		||||
	return c.hashMap[c.keys[idx%len(c.keys)]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Delete 删除一个节点,本质逻辑 : 重建哈希环
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:35 下午 2021/11/21
 | 
			
		||||
func (c *Consistent) Delete(key string) {
 | 
			
		||||
	c.lock.Lock()
 | 
			
		||||
	defer c.lock.Unlock()
 | 
			
		||||
	tmpKeyList := make([]string, 0)
 | 
			
		||||
	for _, k := range c.hashMap {
 | 
			
		||||
		if k == key {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		tmpKeyList = append(tmpKeyList, k)
 | 
			
		||||
	}
 | 
			
		||||
	c.hashMap = make(map[int]string)
 | 
			
		||||
	c.keys = make([]int, 0)
 | 
			
		||||
	c.Add(tmpKeyList...)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								consistent_hash/define.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								consistent_hash/define.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
			
		||||
// Package consistent_hash...
 | 
			
		||||
//
 | 
			
		||||
// Description : consistent_hash...
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-21 4:49 下午
 | 
			
		||||
package consistent_hash
 | 
			
		||||
 | 
			
		||||
import "hash/crc32"
 | 
			
		||||
 | 
			
		||||
// HashFunc 哈希函数定义
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 4:50 下午 2021/11/21
 | 
			
		||||
type HashFunc func(data []byte) uint32
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	// DefaultHashFunc 默认的哈希函数
 | 
			
		||||
	DefaultHashFunc = crc32.ChecksumIEEE
 | 
			
		||||
)
 | 
			
		||||
@ -1,60 +0,0 @@
 | 
			
		||||
// Package excel...
 | 
			
		||||
//
 | 
			
		||||
// Description : 文件类型转换
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 2021-11-19 5:42 下午
 | 
			
		||||
package excel
 | 
			
		||||
 | 
			
		||||
// NewConvert 获取读取实例
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:45 下午 2021/11/19
 | 
			
		||||
func NewConvert(fullFilePath string, filePassword string) (*Convert, error) {
 | 
			
		||||
	var (
 | 
			
		||||
		err  error
 | 
			
		||||
		read *Read
 | 
			
		||||
	)
 | 
			
		||||
	if read, err = NewRead(fullFilePath, filePassword); nil != err {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &Convert{read: read}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Convert 格式状态
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:45 下午 2021/11/19
 | 
			
		||||
type Convert struct {
 | 
			
		||||
	read *Read
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToCSV 转换为CSV
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:46 下午 2021/11/19
 | 
			
		||||
func (c *Convert) ToCSV() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToJSON 转换为JSON
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:46 下午 2021/11/19
 | 
			
		||||
func (c *Convert) ToJSON() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ToTXT 转换为txt
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:47 下午 2021/11/19
 | 
			
		||||
func (c *Convert) ToTXT(splitChar string) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
// Package gin ...
 | 
			
		||||
// Package api ...
 | 
			
		||||
//
 | 
			
		||||
// Description : 便捷的相关API处理
 | 
			
		||||
//
 | 
			
		||||
@ -23,7 +23,7 @@ type IApi interface {
 | 
			
		||||
	GetURI() string
 | 
			
		||||
	// GetMiddleWareList 使用的中间件列表
 | 
			
		||||
	GetMiddleWareList() []gin.HandlerFunc
 | 
			
		||||
	// 处理的handler
 | 
			
		||||
	// GetHandler 处理的handler
 | 
			
		||||
	GetHandler() gin.HandlerFunc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										26
									
								
								util/ip.go
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								util/ip.go
									
									
									
									
									
								
							@ -7,7 +7,10 @@
 | 
			
		||||
// Date : 2021-03-09 5:56 下午
 | 
			
		||||
package util
 | 
			
		||||
 | 
			
		||||
import "net"
 | 
			
		||||
import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// GetHostIP 获取本机IP地址
 | 
			
		||||
//
 | 
			
		||||
@ -27,3 +30,24 @@ func GetHostIP() string {
 | 
			
		||||
	}
 | 
			
		||||
	return hostIP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetRemoteIp 获取远端IP
 | 
			
		||||
//
 | 
			
		||||
// Author : go_developer@163.com<白茶清欢>
 | 
			
		||||
//
 | 
			
		||||
// Date : 5:35 下午 2021/11/22
 | 
			
		||||
func GetRemoteIp(req *http.Request) string {
 | 
			
		||||
 | 
			
		||||
	// Try via request
 | 
			
		||||
 | 
			
		||||
	ip, _, err := net.SplitHostPort(req.RemoteAddr)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "::1"
 | 
			
		||||
	}
 | 
			
		||||
	userIP := net.ParseIP(ip)
 | 
			
		||||
	if userIP == nil {
 | 
			
		||||
		return "::1"
 | 
			
		||||
	}
 | 
			
		||||
	return userIP.String()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user