ruby实现加权轮训

本文介绍了如何使用ruby实现加权轮训算法。假设服务端A权重4,B权重2,C权重1,当服务端接收到7个请求,请求对象的顺序为A,B,C,A,B,A,A。

实现代码

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
module WeightDNS
# 用于存放服务器列表
class Server
def initialize(name, weight)
@name = name
@weight = weight
@visitCount = weight
end

def getWeight
@weight
end

def getName
@name
end

def getVisitCount
@visitCount
end

def setVisitCount(visitCount)
@visitCount = visitCount
end
end

class WeightRound
def initialize(servers)
@curIndex = 0
@servers = servers
@curServer = 0
self.getMaxGcd()
self.getTotalWeight()
end

# 最大公约数算法
def mathgcd(a,b)
if b == 0
return a
end
return mathgcd(b, a % b)
end

# 获取所有IP权重的最大公约数
def getMaxGcd()
tempGcd=0
for server in @servers
weight = server.getWeight
if tempGcd == 0
tempGcd = weight
next
end
tempGcd = mathgcd(tempGcd,weight)
end
@gcd = tempGcd
end

# 获取所有权重总和
def getTotalWeight()
@weightTotal=0
for server in @servers
@weightTotal += server.getWeight
end
@weightTotal /= @gcd
end

# 主入口(获取当期请求的服务器)
def getServer()
serversNum = @servers.length
if @curIndex >= @weightTotal
@curIndex = 0
@curServer = 0
for serverItem in @servers
# p "reset visitCount========" + serverItem.getName
serverItem.setVisitCount(serverItem.getWeight)
end
end
server = @servers[@curServer]
if @curIndex < @weightTotal and server.getVisitCount > 0
server.setVisitCount(server.getVisitCount - @gcd)
# p "Ther server is"+server.getName
@curIndex += 1
@curServer += 1
if @curServer >= serversNum
@curServer = 0
end
return server.getName
end

while true
@curServer += 1
if @curServer >= serversNum
@curServer = 0
end
server = @servers[@curServer]
if @curIndex < @weightTotal and server.getVisitCount > 0
server.setVisitCount(server.getVisitCount - @gcd)
# p "Ther server is"+server.getName
@curIndex += 1
@curServer += 1
if @curServer >= serversNum
@curServer=0
end
return server.getName
end
end
end
end
end

def main()
servers = []
servers.push(WeightDNS::Server.new("192.168.212.190", 3))
servers.push(WeightDNS::Server.new("192.168.212.191", 2))
wr = WeightDNS::WeightRound.new(servers)
for i in 0..19
p wr.getServer()
end
end

结果

1
2
3
4
5
6
7
8
9
10
11
12
13
192.168.212.190
192.168.212.191
192.168.212.190
192.168.212.191
192.168.212.190
192.168.212.190
192.168.212.191
192.168.212.190
192.168.212.191
192.168.212.190
.
.
.
ulysses wechat
订阅+