lab/note/资源/算法/轮询算法.md
张育新 e486d47e2a docs(note): reorganize notes structure and migrate content
- 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
2026-07-15 19:12:07 +08:00

1.8 KiB
Raw Permalink Blame History

轮询算法

平滑加权轮询

原理

每台服务器维护一个 当前权重currentWeight每次选择 currentWeight 最大的服务器,选中后将其 currentWeight 减去总权重,然后所有服务器都加上自己的固定权重。如此循环,高权重节点被选中的频率更高,但不会连续出现。

实际应用

  • Nginxupstream 默认负载均衡算法
  • LVSLinux Virtual Server
  • 几乎所有需要「按比例分配且平滑」的场景

轮询示例

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