go语言实现轮询调度算法

实现轮询调度算法(Round-Robin/rr)的原理是通过取模拿到数组/切片的下标, 从而提取出下一次即将调度的元素. 公式为i = (i + 1) mod n
i为数组下标, n为数组长度
轮询调度算法的优点是无状态, 均匀的将请求调度到后端的每个节点, 并不关心后端每个节点的实际差异

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
package main

import "fmt"

// 声明后端元素的数据结构
type volume struct {
name string
quota int
}

// 声明数据类型存放元素的Slice
type volumes []volume

// 声明并赋值索引下标
var i = -1

// 轮询调度算法
func (v volumes) Select() string {
i = (i + 1) % len(v)
return v[i].name
}

func main(){
v1 := volume{
name: "a",
quota: 4,
}
v2 := volume{
name: "b",
quota: 4,
}
v3 := volume{
name: "c",
quota: 8,
}
v4 := volume{
name: "d",
quota: 2,
}

vo := volumes{
v1, v2, v3, v4,
}

for j := 0; j < 20; j++ {
fmt.Println(j+1, vo.Select())
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1 a
2 b
3 c
4 d
5 a
6 b
7 c
8 d
9 a
10 b
11 c
12 d
13 a
14 b
15 c
16 d
17 a
18 b
19 c
20 d

通过运行结果可以看出, 每次Select请求都被均匀的调度到”后端的节点”. 考虑到后端节点可能存在的差异性, 下篇文章将介绍更为复杂的加权轮询调度算法