-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathloadbalancer.go
145 lines (122 loc) · 3.13 KB
/
loadbalancer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package shlev
import (
"hash/crc32"
"net"
)
// LoadBalancing 负载均衡算法,默认为轮询
type LoadBalancing int
const (
// RoundRobin 轮询
RoundRobin LoadBalancing = iota
// LeastConnections 最小连接
LeastConnections
// SourceAddrHash hash值
SourceAddrHash
)
// loadBalancer 负载均衡接口
type loadBalancer interface {
register(*EventLoop)
next(net.Addr) *EventLoop
iterate(func(int, *EventLoop) bool)
len() int
}
// roundRobinLoadBalancer 轮询负载均衡
type roundRobinLoadBalancer struct {
nextIndex int
eventLoops []*EventLoop
size int
}
// leastConnectionsLoadBalancer 最少连接负载均衡
type leastConnectionsLoadBalancer struct {
eventLoops []*EventLoop
size int
}
// sourceAddrHashLoadBalancer hash负载均衡
type sourceAddrHashLoadBalancer struct {
eventLoops []*EventLoop
size int
}
// ==================================== 轮询负载均衡接口实现 ====================================
// 注册
func (lb *roundRobinLoadBalancer) register(e *EventLoop) {
e.index = lb.size
lb.eventLoops = append(lb.eventLoops, e)
lb.size++
}
// next returns the eligible event-loop based on Round-Robin algorithm.
func (lb *roundRobinLoadBalancer) next(_ net.Addr) (e *EventLoop) {
e = lb.eventLoops[lb.nextIndex]
if lb.nextIndex++; lb.nextIndex >= lb.size {
lb.nextIndex = 0
}
return
}
func (lb *roundRobinLoadBalancer) iterate(f func(int, *EventLoop) bool) {
for i, el := range lb.eventLoops {
if !f(i, el) {
break
}
}
}
func (lb *roundRobinLoadBalancer) len() int {
return lb.size
}
// ================================= 最小连接负载均衡接口实现 =================================
func (lb *leastConnectionsLoadBalancer) min() (el *EventLoop) {
el = lb.eventLoops[0]
minN := el.loadConn()
for _, v := range lb.eventLoops[1:] {
if n := v.loadConn(); n < minN {
minN = n
el = v
}
}
return
}
func (lb *leastConnectionsLoadBalancer) register(el *EventLoop) {
el.index = lb.size
lb.eventLoops = append(lb.eventLoops, el)
lb.size++
}
// next 返回可用的EventLoop
func (lb *leastConnectionsLoadBalancer) next(_ net.Addr) (el *EventLoop) {
return lb.min()
}
func (lb *leastConnectionsLoadBalancer) iterate(f func(int, *EventLoop) bool) {
for i, el := range lb.eventLoops {
if !f(i, el) {
break
}
}
}
func (lb *leastConnectionsLoadBalancer) len() int {
return lb.size
}
// ======================================= 哈希负载均衡接口实现 ========================================
func (lb *sourceAddrHashLoadBalancer) register(el *EventLoop) {
el.index = lb.size
lb.eventLoops = append(lb.eventLoops, el)
lb.size++
}
// hash 算hash值
func (lb *sourceAddrHashLoadBalancer) hash(s string) int {
v := int(crc32.ChecksumIEEE([]byte(s)))
if v >= 0 {
return v
}
return -v
}
func (lb *sourceAddrHashLoadBalancer) next(netAddr net.Addr) *EventLoop {
hashCode := lb.hash(netAddr.String())
return lb.eventLoops[hashCode%lb.size]
}
func (lb *sourceAddrHashLoadBalancer) iterate(f func(int, *EventLoop) bool) {
for i, el := range lb.eventLoops {
if !f(i, el) {
break
}
}
}
func (lb *sourceAddrHashLoadBalancer) len() int {
return lb.size
}