@@ -38,82 +38,47 @@ func (pp PortPools) Names() string {
38
38
// 从所有端口池中都分配出指定端口,不同端口池可分配不同端口
39
39
func (pp PortPools ) allocatePortAcrossPools (
40
40
ctx context.Context ,
41
- startPort , endPort , quota , segmentLength uint16 ,
42
- getPortsToAllocate func (port , endPort uint16 ) (ports []ProtocolPort ),
43
- ) (PortAllocations , error ) {
41
+ startPort , endPort , quota , segmentLength uint16 , protocol string ,
42
+ ) PortAllocations {
44
43
log .FromContext (ctx ).V (10 ).Info ("allocatePortAcrossPools" , "pools" , pp .Names (), "startPort" , startPort , "endPort" , endPort , "segmentLength" , segmentLength )
45
44
var allocatedPorts PortAllocations
46
- LOOP_POOL:
47
45
for _ , pool := range pp { // 遍历所有端口池(由于不需要保证所有端口池的端口号相同,因此外层循环直接遍历端口池)
48
- for port := startPort ; port <= endPort ; port += segmentLength { // 遍历该端口池的所有端口号
49
- select {
50
- case <- ctx .Done ():
51
- allocatedPorts .Release ()
52
- if err := ctx .Err (); err != nil {
53
- return nil , errors .WithStack (err )
54
- }
55
- return nil , nil
56
- default :
57
- }
58
- endPort := uint16 (0 )
59
- if segmentLength > 1 {
60
- endPort = port + segmentLength - 1
61
- }
62
- portsToAllocate := getPortsToAllocate (port , endPort )
63
- // 尝试分配端口
64
- result , quotaExceeded := pool .AllocatePort (ctx , int64 (quota ), portsToAllocate ... )
65
- if quotaExceeded { // 超配额,不可能分配成功,不再继续尝试
66
- allocatedPorts .Release ()
67
- return nil , nil
68
- }
69
- if len (result ) > 0 { // 该端口池分配到了端口,追加到结果中
70
- allocatedPorts = append (allocatedPorts , result ... )
71
- log .FromContext (ctx ).V (10 ).Info ("allocated port" , "pool" , pool .Name , "port" , port )
72
- continue LOOP_POOL
73
- } else {
74
- // 该端口池中无法分配此端口,尝试下一个端口
75
- log .FromContext (ctx ).V (10 ).Info ("no available port can be allocated, try next port" , "pool" , pool .Name , "port" , port )
76
- continue
77
- }
46
+ // 尝试分配端口
47
+ result , quotaExceeded := pool .AllocatePortFromRange (ctx , startPort , endPort , quota , segmentLength , protocol )
48
+ if quotaExceeded { // 超配额,不可能分配成功,不再继续尝试
49
+ allocatedPorts .Release ()
50
+ return nil
51
+ }
52
+ if len (result ) > 0 { // 该端口池分配到了端口,追加到结果中
53
+ allocatedPorts = append (allocatedPorts , result ... )
54
+ log .FromContext (ctx ).V (10 ).Info ("allocated port" , "pool" , pool .Name , "ports" , allocatedPorts )
55
+ } else { // 只要有一个端口池分配失败,则认为无法分配,释放已分配端口,等待 lb 扩容
56
+ allocatedPorts .Release ()
57
+ return nil
78
58
}
79
- // 该端口池所有端口都无法分配,不再尝试
80
- allocatedPorts .Release ()
81
- return nil , nil
82
59
}
83
60
// 所有端口池都分配成功,返回结果
84
- return allocatedPorts , nil
61
+ return allocatedPorts
85
62
}
86
63
87
64
// 从所有端口池中都分配出指定端口,不同端口池必须分配相同端口
88
65
func (pp PortPools ) allocateSamePortAcrossPools (
89
66
ctx context.Context ,
90
- startPort , endPort , quota , segmentLength uint16 ,
91
- getPortsToAllocate func (port , endPort uint16 ) (ports []ProtocolPort ),
92
- ) (PortAllocations , error ) {
67
+ startPort , endPort , quota , segmentLength uint16 , protocol string ,
68
+ ) PortAllocations {
93
69
log .FromContext (ctx ).Info ("allocateSamePortAcrossPools" , "pools" , pp .Names (), "startPort" , startPort , "endPort" , endPort , "segmentLength" , segmentLength )
94
70
LOOP_PORT:
95
71
for port := startPort ; port <= endPort ; port += segmentLength { // 遍历所有端口号,确保所有端口池都能分配到相同端口号
96
72
endPort := uint16 (0 )
97
73
if segmentLength > 1 {
98
74
endPort = port + segmentLength - 1
99
75
}
100
- portsToAllocate := getPortsToAllocate (port , endPort )
101
76
var allocatedPorts PortAllocations
102
77
for _ , pool := range pp { // 在所有端口池中查找可用端口,TCP 和 UDP 端口号相同且都未被分配,则分配此端口号
103
- select {
104
- case <- ctx .Done ():
105
- allocatedPorts .Release ()
106
- if err := ctx .Err (); err != nil {
107
- return nil , errors .WithStack (err )
108
- }
109
- return nil , nil
110
- default :
111
- }
112
-
113
- results , quotaExceeded := pool .AllocatePort (ctx , int64 (quota ), portsToAllocate ... )
78
+ results , quotaExceeded := pool .AllocatePort (ctx , int64 (quota ), port , endPort , protocol )
114
79
if quotaExceeded {
115
80
allocatedPorts .Release ()
116
- return nil , nil
81
+ return nil
117
82
}
118
83
if len (results ) > 0 {
119
84
// 此端口池分配到了此端口,追加到结果中
@@ -124,10 +89,10 @@ LOOP_PORT:
124
89
}
125
90
}
126
91
// 分配结束,返回结果可能为空)
127
- return allocatedPorts , nil
92
+ return allocatedPorts
128
93
}
129
94
// 所有端口池都无法分配,返回空结果
130
- return nil , nil
95
+ return nil
131
96
}
132
97
133
98
var (
@@ -136,6 +101,28 @@ var (
136
101
ErrPortPoolNotAllocatable = errors .New ("port pool not allocatable" )
137
102
)
138
103
104
+ func portsToAllocate (port , endPort uint16 , protocol string ) (ports []ProtocolPort ) {
105
+ if protocol == constant .ProtocolTCPUDP {
106
+ ports = append (ports , ProtocolPort {
107
+ Port : port ,
108
+ Protocol : constant .ProtocolTCP ,
109
+ EndPort : endPort ,
110
+ })
111
+ ports = append (ports , ProtocolPort {
112
+ Port : port ,
113
+ Protocol : constant .ProtocolUDP ,
114
+ EndPort : endPort ,
115
+ })
116
+ } else {
117
+ ports = append (ports , ProtocolPort {
118
+ Port : port ,
119
+ Protocol : protocol ,
120
+ EndPort : endPort ,
121
+ })
122
+ }
123
+ return
124
+ }
125
+
139
126
// 从一个或多个端口池中分配一个指定协议的端口,分配成功返回端口号,失败返回错误
140
127
func (pp PortPools ) AllocatePort (ctx context.Context , protocol string , useSamePortAcrossPools bool ) (ports PortAllocations , err error ) {
141
128
startPort := uint16 (0 )
@@ -187,66 +174,10 @@ func (pp PortPools) AllocatePort(ctx context.Context, protocol string, useSamePo
187
174
segmentLength = 1
188
175
}
189
176
190
- getPortsToAllocate := func (port , endPort uint16 ) (ports []ProtocolPort ) {
191
- if protocol == constant .ProtocolTCPUDP {
192
- ports = append (ports , ProtocolPort {
193
- Port : port ,
194
- Protocol : constant .ProtocolTCP ,
195
- EndPort : endPort ,
196
- })
197
- ports = append (ports , ProtocolPort {
198
- Port : port ,
199
- Protocol : constant .ProtocolUDP ,
200
- EndPort : endPort ,
201
- })
202
- } else {
203
- ports = append (ports , ProtocolPort {
204
- Port : port ,
205
- Protocol : protocol ,
206
- EndPort : endPort ,
207
- })
208
- }
209
- return
210
- }
211
-
212
177
if useSamePortAcrossPools {
213
- ports , err = pp .allocateSamePortAcrossPools (ctx , startPort , endPort , quota , segmentLength , getPortsToAllocate )
178
+ ports = pp .allocateSamePortAcrossPools (ctx , startPort , endPort , quota , segmentLength , protocol )
214
179
} else {
215
- ports , err = pp .allocatePortAcrossPools (ctx , startPort , endPort , quota , segmentLength , getPortsToAllocate )
216
- }
217
- if err != nil {
218
- return nil , errors .WithStack (err )
180
+ ports = pp .allocatePortAcrossPools (ctx , startPort , endPort , quota , segmentLength , protocol )
219
181
}
220
182
return ports , nil
221
183
}
222
-
223
- // func (pp PortPools) ReleasePort(lbId string, port uint16, protocol string) {
224
- // if protocol == "TCPUDP" {
225
- // tcpPort := ProtocolPort{
226
- // Port: port,
227
- // Protocol: "TCP",
228
- // }
229
- // udpPort := ProtocolPort{
230
- // Port: port,
231
- // Protocol: "UDP",
232
- // }
233
- // for _, portPool := range pp {
234
- // if portCache := portPool.cache[lbId]; portCache != nil {
235
- // delete(portCache, tcpPort)
236
- // delete(portCache, udpPort)
237
- // break
238
- // }
239
- // }
240
- // } else {
241
- // port := ProtocolPort{
242
- // Port: port,
243
- // Protocol: protocol,
244
- // }
245
- // for _, portPool := range pp {
246
- // if portCache := portPool.cache[lbId]; portCache != nil {
247
- // delete(portCache, port)
248
- // break
249
- // }
250
- // }
251
- // }
252
- // }
0 commit comments