- Move Windows and 算法 notes from 随手记 to 资源 directory - Migrate Golang map pitfalls and dot import notes to Golang/使用注意 - Delete omos配置 note - Add Typora custom theme reference link
57 lines
1.8 KiB
Markdown
57 lines
1.8 KiB
Markdown
## 轮询算法
|
||
|
||
### 平滑加权轮询
|
||
|
||
#### 原理
|
||
|
||
每台服务器维护一个 `当前权重`(currentWeight),每次选择 `currentWeight` 最大的服务器,选中后将其 `currentWeight` 减去总权重,然后**所有服务器都加上自己的固定权重**。如此循环,高权重节点被选中的频率更高,但不会连续出现。
|
||
|
||
#### 实际应用
|
||
|
||
- **Nginx** 的 `upstream` 默认负载均衡算法
|
||
- **LVS**(Linux Virtual Server)
|
||
- 几乎所有需要「按比例分配且平滑」的场景
|
||
|
||
#### 轮询示例
|
||
|
||
```go
|
||
type server struct {
|
||
name string
|
||
weight int
|
||
curWeight int
|
||
}
|
||
|
||
func NextServer(servers []*server) *server {
|
||
var totalWeight int
|
||
// 1.先给所有服务器加上各自的固定权重
|
||
for i := range servers {
|
||
servers[i].curWeight += servers[i].weight
|
||
totalWeight += servers[i].weight
|
||
}
|
||
// 2.再找出 curWeight 最大的服务器
|
||
maxIdx := 0
|
||
for i := 1; i < len(servers); i++ {
|
||
if servers[i].curWeight > servers[maxIdx].curWeight {
|
||
maxIdx = i
|
||
}
|
||
}
|
||
// 3.选中的服务器减去总权重
|
||
servers[maxIdx].curWeight -= totalWeight
|
||
return servers[maxIdx]
|
||
}
|
||
```
|
||
|
||
| 轮次 | 操作前 (currentWeight) | 选中 | 操作后 |
|
||
| ---- | ---------------------- | ----- | --------------- |
|
||
| 初始 | A=0, B=0, C=0 | — | — |
|
||
| 1 | A=5, B=1, C=1 | **A** | A=−2, B=1, C=1 |
|
||
| 2 | A=3, B=2, C=2 | **A** | A=−4, B=2, C=2 |
|
||
| 3 | A=1, B=3, C=3 | **B** | A=1, B=−4, C=3 |
|
||
| 4 | A=6, B=−3, C=4 | **A** | A=−1, B=−3, C=4 |
|
||
| 5 | A=4, B=−2, C=5 | **C** | A=4, B=−2, C=−2 |
|
||
| 6 | A=9, B=−1, C=−1 | **A** | A=2, B=−1, C=−1 |
|
||
| 7 | A=7, B=0, C=0 | **A** | A=0, B=0, C=0 |
|
||
|
||
|
||
|