技术研究 | 微服务网关负载均衡技术

2026-03-25 · Henry

负载均衡(Load Balancing)是将请求分配到多个后端实例的技术。它的核心不是随机分发请求,而是解决三个工程问题: - 可用性:单实例故障时,流量可自动切换。 - 性能:避免热点实例过载,提升整体吞吐。 - 可扩展性:新增/移除实例时,网关仍能稳定工作。 在网关层实现负载均衡,可以把流量治理能力前置,后端服务只专注业务逻辑。

1. 负载均衡技术 负载均衡(Load Balancing)是将请求分配到多个后端实例的技术。它的核心不是随机分发请求,而是解决三个工程问题: 可用性:单实例故障时,流量可自动切换。 性能:避免热点实例过载,提升整体吞吐。 可扩展性:新增/移除实例时,网关仍能稳定工作。 在网关层实现负载均衡,可以把流量治理能力前置,后端服务只专注业务逻辑。 下面,将以 Yuelai Engine 微服务网关项目负载均衡模块为案例,对该技术进行说明。 2. 定义负载均衡器接口 为什么要先做接口抽象? 上层调用不关心算法细节(RR/WRR/LC/CH)。 算法可替换、可扩展。 健康状态同步与连接归还可以统一治理。 代码案例 这段设计体现了两点: LoadBalancer 负责通用能力。 HashLoadBalancer 负责按 key 选点能力,避免把所有算法写进塞进一个接口。 3. 工厂模式:算法选择与生命周期管理 工厂模式是常见的设计模式,在我的 Wiki 中有详细说明。 为什么需要工厂? 服务维度缓存 balancer,避免重复创建。 配置变更时可整体替换实例池。 支持不同服务使用不同算法。 代码案例 这里的关键点是“双重检查 + 锁粒度控制”,避免并发重复创建,也规避了读写锁升级死锁风险。 4. Round Robin 最简单的基线策略 RR 的核心思想:按顺序轮流分配请求。 适合场景: 实例规格接近 请求耗时相近 追求简单稳定 为什么这样实现 使用 atomic.Uint64 做全局游标,保证并发安全。 先过滤健康实例,再取模选点,确保不会命中明显故障节点。 代码案例 5. Weighted Round Robin 实例能力差异纳入调度 WRR 的核心思想:按权重比例分流。 适合场景: 实例规格不一致 灰度引流(例如 90/10) 为什么这样实现 正权重实例参与加权池。 当权重无效(全 0 或负数)时,回退到普通 RR,避免异常配置导致崩溃或偏斜。 代码案例 6. Least Connections 面向实时负载的策略 LC 的核心思想:优先把请求给当前连接数最少的实例。 适合场景: 请求耗时差异大 存在慢请求 需要动态反映实例压力 为什么这样实现 选中实例时 Connections++。 请求完成后通过 ReleaseConnection 归还计数。 避免只加不减导致调度永久偏斜。 代码案例 7. Consistent Hash 稳定路由与会话亲和 一致性哈希的核心价值:同一个 key(如 userID)稳定映射到同一实例。 适合场景: 会话粘性 本地缓存命中优化 分片稳定性要求高 为什么这样实现 使用虚拟节点降低哈希倾斜。 ring 上二分查找,查询复杂度稳定。 实例健康变化时重建 ring,避免继续命中不健康节点。 代码案例 8. Health Checker 为什么健康检查非常关键? 不做检查:调度算法再好,也可能把请求发给异常实例。 做好检查:故障实例能被快速摘除,恢复后可自动回归。 代码案例 这里返回 error 的设计也很关键:避免静默失败。 9. 并发安全 在高并发网关中,负载均衡模块是热点路径。并发安全不是优化项,而是必须项。 高频游标用原子变量(atomic.Uint64) 结构状态更新用互斥锁 不在 RLock 下执行写操作 错误路径显式返回 这套策略能显著降低竞态、死锁和状态漂移风险。 10. 如何评估一个负载均衡实现是否靠谱 大概从四类维度评估: 分配准确性:是否符合 RR/WRR/LC/CH 预期行为 故障处理:实例 unhealthy 后是否及时摘除 并发正确性:是否可通过 race 检测 工程可维护性:接口是否稳定、测试是否可回归 11. 总结 负载均衡从来不是选一个实例这么简单,它本质是: 策略选择(RR/WRR/LC/CH) 健康状态治理 并发安全控制 统一接口抽象 可测试、可演进的工程实现 目前,Yuelai Engine 微服务网关还在开发中,期待后续上线实践。