线上随机负载均衡总打到同一台机器,是因为未初始化随机种子导致rand.intn生成固定序列;需启动时调用rand.seed或使用rand.new,避免全局状态问题。

Go 里 rand.Intn 做随机负载均衡,为什么线上总打到同一台机器?
因为没初始化随机种子,rand.Intn 每次启动都生成相同序列。服务一重启,所有请求按固定顺序打到同一台实例,看起来像“随机失效”。
- 必须在程序启动时调用
rand.Seed(time.Now().UnixNano())(Go 1.20+ 推荐直接用rand.New(rand.NewSource(time.Now().UnixNano()))避免全局状态) - 如果用的是 HTTP 中间件或 goroutine 复用场景,别在 handler 里反复 new rand.Rand——开销小但没必要,全局复用一个即可
- 真实压测中,纯随机在节点数变化时无法保证流量重分布均匀,适合节点稳定、数量少(≤5)的内部服务
轮询(Round Robin)在 Go 的 net/http.RoundTripper 中怎么安全实现?
标准库不提供带状态的轮询,自己写容易在并发下丢计数或 panic。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
- 用
sync/atomic管理索引:定义type roundRobin struct { idx int64 },每次atomic.AddInt64(&rr.idx, 1)后取模 - 别用
map或切片做后端列表的深拷贝——轮询过程中列表可能被热更新,应配合sync.RWMutex读锁保护只读访问 - 注意零值陷阱:如果后端列表为空,
% 0会 panic,务必前置校验并返回错误或 fallback
一致性哈希为啥选 hashicorp/go-immutable-radix 而不是手撸 sha256.Sum256?
一致性哈希的关键不在哈希函数本身,而在虚拟节点管理与查找效率。手算 hash + 二分查找 O(log N) 是底线,但增删节点时的 rehash 成本和内存占用常被忽略。
-
go-immutable-radix提供线程安全的IRadix树,支持动态增删节点且查找是 O(log N),比自己维护排序切片+二分更稳 - 别直接用
sha256.Sum256对节点名哈希——它输出 32 字节,作为环坐标易冲突;应转成 uint64 或映射到 [0, 2^32) 区间再散列 - 虚拟节点数设为 100–200 是经验值:太少则倾斜明显(尤其节点数<5),太多则内存占用陡增且收益递减
三种算法混用时,context.Context 里该传哪个负载策略?
不能靠中间件统一决策。不同接口对延迟、一致性、容错的要求差异极大,硬绑定一种策略反而放大故障面。
- 把策略选择下沉到具体 client 初始化逻辑,例如
NewUserClient(opts ...ClientOption)支持传WithLoadBalancer(LBStrategy) - 避免在
context.WithValue里塞策略实例——生命周期难管理,且 http.Handler 链路中易被覆盖或遗忘 - 最易被忽略的一点:健康检查必须和负载策略联动。轮询遇到宕机节点要跳过,一致性哈希遇到节点下线要快速剔除其虚拟节点,否则请求会卡死在失败连接上
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










