lab/note/随手记/算法.md
张育新 be711334fb docs(note): 添加笔记目录及 gitignore 规则
- 新增 note 目录包含 AI、SQL、Golang、网络等多领域学习笔记
- 更新 .gitignore 添加 note/assets/ 和 note/项目/ 忽略规则
2026-07-10 09:24:40 +08:00

57 lines
1.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 轮询算法
### 平滑加权轮询
#### 原理
每台服务器维护一个 `当前权重`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 |