云计算百科
云计算领域专业知识百科平台

把流量送到正确的地方:负载均衡的原理、算法与四层/七层工程实践

目录

一、负载均衡的意义:它分配的不只是请求

(一)从单机瓶颈到资源池

1、单机为什么迟早会碰到边界

2、吞吐、时延与利用率之间的平衡

3、容量扩展不是简单相加

(二)高可用来自快速发现与有序切换

1、冗余只有被正确调度才有价值

2、故障摘除只是恢复链条的一环

(三)负载均衡也是发布与治理平台

1、把版本变更转化为流量变更

2、建立统一的安全和可观测入口

二、一次请求怎样穿过负载均衡系统

(一)数据平面与控制平面分工

1、数据平面负责“快而确定”

2、控制平面负责“知道该往哪里送”

(二)后端候选集合如何形成

1、服务发现提供“有哪些实例”

2、健康检查回答“现在是否适合接流量”

(三)选择、转发与返回

1、选择阶段先过滤再打分

2、转发可以是改包,也可以是代理

三、负载均衡的实现方式:能力分布在哪里

(一)入口侧的三类实现

1、DNS 与全局流量调度

2、四层网络负载均衡

3、七层反向代理

(二)服务侧的三类实现

1、客户端负载均衡

2、服务网格与边车/节点代理

3、服务端分派与工作队列

(三)单层方案与组合方案

1、为什么生产系统常常多层并存

2、旁路与降级路径必须提前设计

四、负载均衡算法:从“分得平均”到“适应系统”

(一)静态算法:低成本建立基本秩序

1、轮询与加权轮询

1.1 普通轮询

1.2 加权轮询

2、随机与加权随机

(二)动态算法:用实时状态修正分配

1、最少连接与最少请求

1.1 最少连接

1.2 最少未完成请求

2、最短响应时间与自适应权重

2.1 延迟感知

2.2 后端主动上报

3、P2C:在效果与复杂度之间折中

(三)哈希算法:用稳定映射换取局部性

1、普通哈希与会话粘性

2、一致性哈希

3、Rendezvous 与 Maglev

(四)算法选择不能脱离工作负载

1、算法比较表

2、一个实用选择顺序

五、四层负载均衡:以连接和数据包为中心

(一)四层究竟能看见什么

1、五元组与连接一致性

2、TLS 直通时看不到 HTTP 内容

(二)四层的常见数据路径

1、NAT:易理解但要规划回程

2、直接路由与直接服务器返回

3、四层全代理

(三)四层的优势与边界

1、优势

2、边界

六、七层负载均衡:以请求语义为中心

(一)七层代理如何处理一条请求

1、终止、解析、匹配、转发

2、连接池改变了“连接数”的含义

(二)七层提供的核心能力

1、内容路由与多服务复用

2、TLS、安全与协议规范化

3、可靠性与交付治理

(三)七层的成本与风险

1、计算与延迟成本

2、语义错误与集中风险

七、四层与七层的区别:不是简单的性能二选一

(一)核心差异对照

1、能力矩阵

2、“第几层”是工程简称,不是完整架构描述

(二)性能差异应怎样理解

1、四层通常更轻,但不是无成本

2、七层增加处理,也可能改善端到端性能

(三)什么时候组合使用

1、常见组合:四层入口加七层网关

2、服务间再使用客户端或网格调度

八、健康检查、会话与失败治理

(一)健康检查是一台状态机

1、阈值、迟滞与抖动

2、排空、预热与慢启动

(二)会话保持是权衡,不是默认答案

1、为什么需要粘性

2、粘性带来的代价

(三)超时、重试、熔断和背压要协同

1、超时是资源预算

2、重试必须有预算

3、熔断与背压防止扩散

九、生产实现:从需求到验证的完整方法

(一)先定义目标与流量画像

1、回答七个基础问题

2、用分布而不是平均值描述负载

(二)设计数据面、控制面与故障域

1、数据面容量与冗余

2、控制面安全与回滚

3、故障域优先于算法

(三)配置示例与实现要点

1、NGINX 四层 TCP 示例

2、NGINX 七层 HTTP 示例

3、Kubernetes Service 与网关

(四)测试要覆盖正常与异常

1、基准与容量测试

2、故障注入

3、分布正确性测试

十、可观测性:证明流量真的被均衡

(一)指标要能回答“谁慢、为什么慢”

1、入口指标

2、后端维度

3、分布偏斜指标

(二)日志、追踪与配置版本

1、访问日志需要上下游关联

2、分布式追踪揭示排队位置

3、配置版本必须进入遥测

十一、典型场景如何选择

(一)面向公网的 Web 与 API

1、推荐思路

2、注意事项

(二)数据库、消息队列与自定义 TCP

1、推荐思路

2、注意事项

(三)WebSocket、游戏与实时通信

1、推荐思路

2、注意事项

(四)缓存与对象分片

1、推荐思路

2、注意事项

(五)UDP、QUIC 与 HTTP/3

1、推荐思路

2、注意事项

十二、常见误区与失败模式

(一)把均匀请求数当成均匀负载

1、为什么会错

2、怎样修正

(二)把健康检查写成“永远成功”

1、为什么会错

2、怎样修正

(三)无限重试“提高成功率”

1、为什么会错

2、怎样修正

(四)粘性会话被当成高可用

1、为什么会错

2、怎样修正

(五)忽略负载均衡器自身故障

1、为什么会错

2、怎样修正

十三、进一步思考:负载均衡是一套反馈控制系统

(一)调度器为什么会振荡

1、延迟反馈与羊群效应

2、稳定性设计

(二)局部最优可能损害全局

1、把请求送到最快节点未必最便宜

2、多目标调度需要优先级

(三)未来方向:从代理中心到协同调度

1、内核与硬件数据面

2、应用成本感知

3、AI 可以辅助,但不应绕过安全边界

十四、总结:正确的负载均衡是一种系统能力

(一)四个结论

1、意义

2、实现

3、算法

4、四层与七层

(二)一份落地检查清单

1、设计前

2、上线前

3、运行中

可参考的文章与规范


干货分享,感谢您的阅读!

负载均衡的表面任务,是把请求分给多台服务器;它的真正价值,是在容量、时延、故障、成本和发布风险之间建立一套可持续的流量秩序。一次正确的后端选择只是起点,完整系统还要回答:后端从哪里来、怎样判断健康、连接是否需要保持、失败能否重试、扩缩容如何平滑、调度效果如何验证,以及调度器自身发生故障时谁来接管。

本文面向需要建立系统化认识的研发、运维、架构与技术管理人员。我们先从负载均衡的意义讲起,再沿着一次请求的生命周期说明实现机制,随后梳理算法谱系,深入比较四层与七层方案,最后给出生产落地、故障治理和选型方法。文中的架构图均重新绘制,采用统一配色与中文标注;公式、配置和数字仅用于解释方法,不能代替针对实际业务的压测。

一、负载均衡的意义:它分配的不只是请求

(一)从单机瓶颈到资源池

1、单机为什么迟早会碰到边界

任何单机都有可量化的上限:CPU 每秒能执行的指令有限,内存能容纳的工作集有限,网卡和系统总线有吞吐上限,文件描述符、连接跟踪表和端口空间也不是无限的。应用还会受到数据库连接池、运行时停顿、锁竞争、磁盘 I/O、外部接口限额等约束。把机器不断升级可以延后问题,却无法消除硬件故障,也无法让维护、发布和扩容变得无感。

更关键的是,业务负载通常并不平稳。白天与夜间、工作日与节假日、常态与营销活动之间可能相差数倍乃至数十倍。若系统只能依靠一台机器,就只能按峰值预留资源,同时接受“一个故障点决定整个服务命运”的事实。将能力拆成多个实例并组成资源池,才可能用横向扩展换取容量弹性,用冗余换取可用性。

负载均衡器站在资源池入口,对外暴露稳定地址,对内维护可用后端集合。客户端不必知道真实实例数量、地址和生命周期,只需访问一个逻辑服务。扩容时加入实例,缩容或维修时移出实例,入口保持不变。这种“稳定接口与动态资源解耦”的能力,往往比单纯平均分流更重要。

2、吞吐、时延与利用率之间的平衡

理想的调度并不是让每台服务器收到完全相同的请求数,而是让系统在目标服务质量下承载更多有效工作。若所有请求成本一致、所有后端能力相同,轮询确实可能接近均衡;但现实中,请求可能查询一行数据,也可能生成一份报表,实例可能处于不同机型、不同可用区或不同预热阶段。只数请求,容易得到“数量平均、耗时失衡”的结果。

因此,负载均衡至少同时关心三类量:

  • 输入强度:每秒新连接数、每秒请求数、字节吞吐和并发流数;

  • 服务成本:处理时间、CPU 时间、内存占用、下游调用和响应体大小;

  • 结果质量:成功率、尾时延、超时比例、重试量和业务完成率。

当到达速率长期逼近服务速率时,队列会积累,尾时延往往在平均利用率看似尚可时就开始恶化。负载均衡不能创造后端不存在的容量,但可以避免局部热点提前把整个系统拖入排队区,也可以把过载信号转化为限流、降级或扩容动作。

3、容量扩展不是简单相加

假设三台服务器各自压测上限为 1000 请求/秒,集群并不必然稳定承载 3000 请求/秒。负载均衡器自身会消耗资源;共享数据库可能先到上限;实例间能力存在方差;故障时还要为剩余节点保留接管空间。更稳妥的容量表达是:

可承诺容量 ≈ 健康实例能力之和 × 安全系数 − 故障预留 − 共享瓶颈影响。

安全系数取决于业务波动、扩容速度和性能曲线,不能照抄固定百分比。生产设计应以故障场景下的有效容量为基准,例如要求“任一可用区失效后仍满足核心流量”,而不是只计算所有节点全部健康时的理论峰值。

负载均衡把容量扩展、故障隔离、发布治理和统一入口连接成一条价值链。

(二)高可用来自快速发现与有序切换

1、冗余只有被正确调度才有价值

部署两台服务器并不等于高可用。如果入口仍固定指向其中一台,或者故障节点无法被及时识别,冗余只是一份闲置副本。负载均衡通过健康检查、被动错误统计和服务发现,把“某个实例是否应该接收新流量”变成持续更新的判断。

健康并不是二元且永恒的属性。实例可能进程存活但线程池耗尽,端口可连但数据库依赖失效,首页返回 200 但核心交易失败,也可能只是短暂抖动。成熟系统会区分存活、就绪、降级、排空、异常和恢复预热等状态,并用连续成功/失败阈值抑制频繁切换。

2、故障摘除只是恢复链条的一环

负载均衡器发现异常后停止分配新请求,可以限制故障半径;但已建立的长连接怎么办、未完成请求是否可重放、会话状态是否还在故障节点、剩余节点是否有接管容量,这些问题决定用户是否真正无感。

因此,高可用链条通常包括:

  • 发现:主动探测与真实流量反馈识别异常;

  • 隔离:将异常实例从候选集合中移除;

  • 承接:健康实例吸收转移流量,同时防止过载;

  • 恢复:实例修复后先预热,再逐步放量;

  • 验证:观察错误率、尾时延与容量水位,确认恢复稳定。

  • 如果只有“摘除”而没有容量预留、连接排空和慢启动,故障流量会像水锤一样冲向其余节点,造成级联故障。高可用的本质不是永不失败,而是失败发生后仍能维持可接受服务,并以受控方式恢复。

    (三)负载均衡也是发布与治理平台

    1、把版本变更转化为流量变更

    应用发布最危险的时刻,往往是新旧版本同时存在时。具备权重、路由规则和健康反馈的负载均衡层,可以让新版本先接收 1% 或特定测试用户的流量,验证后逐级扩大;如果指标恶化,立即把权重调回旧版本。蓝绿发布、金丝雀发布、A/B 实验、影子流量,本质上都在利用可编程的流量选择能力。

    2、建立统一的安全和可观测入口

    七层负载均衡器能在 HTTP 语义上执行 TLS 终止、身份校验、请求大小限制、WAF、跨域策略、Header 规范化、速率限制和访问日志。把通用能力放在入口,可减少每个业务重复实现,但同时也意味着入口配置错误会影响大范围流量,必须有配置审查、灰度发布、回滚和审计机制。

    四层方案虽然看不到 URL 与 Cookie,仍可以提供 DDoS 清洗衔接、连接速率限制、源地址保留、网络级访问控制、统一 VIP 和连接指标。负载均衡不是某一台设备的专属能力,而是一组可分布在 DNS、网络、代理、客户端和服务网格中的流量控制功能。

    二、一次请求怎样穿过负载均衡系统

    (一)数据平面与控制平面分工

    1、数据平面负责“快而确定”

    数据平面直接处理连接或请求。它读取必要的匹配键,查询候选后端,执行算法,完成地址转换、转发或代理,并记录少量统计。高吞吐场景要求这条路径尽可能短、锁竞争尽可能少,常见实现会使用内核转发、事件驱动代理、连接池、零拷贝或批处理等技术。

    数据平面必须对同一条连接保持一致处理。TCP 包不能在连接中途随意改投另一台服务器,否则序列号和连接状态无法衔接;UDP 虽然无连接,负载均衡器通常也会为一段时间内的四元组或五元组维持会话映射。七层代理则可以在连接内按请求选择后端,但 HTTP/2、gRPC 和 HTTP/3 的多路复用会让“连接”和“请求”不再一一对应。

    2、控制平面负责“知道该往哪里送”

    控制平面维护监听器、路由规则、后端列表、权重、证书、健康状态和策略。它从服务注册中心、编排平台、配置仓库或云控制面接收变化,校验后下发给数据平面。控制平面可以稍慢,但必须防止错误配置一次性扩散。

    两者分离带来一个重要原则:控制面短暂不可用时,数据面应尽量继续使用最近一次有效配置转发;数据面故障时,控制面应能把入口切换到其他实例。 如果每个请求都实时依赖注册中心查询,注册中心抖动会被直接放大为业务故障。

    控制平面提供后端与策略,数据平面执行转发,健康检查和业务指标形成反馈闭环。

    (二)后端候选集合如何形成

    1、服务发现提供“有哪些实例”

    候选后端可以来自静态配置、DNS 记录、注册中心、Kubernetes EndpointSlice、云厂商目标组或 xDS 等动态接口。服务发现解决地址变化问题,但“被发现”不等于“可接流量”。新实例可能尚未加载缓存,旧实例可能正在排空,某个节点可能仅对部分协议就绪。

    一个稳健候选集合通常要依次通过:注册状态、就绪状态、健康状态、优先级/地域约束、熔断容量和路由条件。算法只在过滤后的集合中选择。把失效实例混入算法,再指望重试补救,会制造额外时延和重试风暴。

    2、健康检查回答“现在是否适合接流量”

    主动检查由负载均衡器定期发起,可以是 TCP 连接、特定字节收发、HTTP 路径、gRPC 健康协议或业务自检;被动检查根据真实请求的连接失败、超时、状态码和延迟识别异常。主动检查覆盖空闲节点,被动检查更接近用户体验,两者结合比单独使用更可靠。

    检查路径应覆盖关键依赖,但不宜执行昂贵业务。过浅会把“进程还活着”误判为“服务可用”,过深又可能让健康检查本身压垮数据库。常见做法是区分:

    • 存活检查:进程是否需要重启;

    • 就绪检查:实例能否接收新流量;

    • 业务探针:关键依赖和核心路径是否满足服务条件。

    (三)选择、转发与返回

    1、选择阶段先过滤再打分

    选择过程可以抽象为:

  • 按协议、端口、Host、路径、方法、Header、地域或租户筛选路由;

  • 排除未就绪、异常、排空和达到并发上限的后端;

  • 根据优先级选择主区域或故障转移区域;

  • 在剩余集合上执行轮询、最少连接、哈希或自适应算法;

  • 创建连接映射或把请求交给已有上游连接。

  • 顺序很重要。路由规则决定“在哪个池里选”,算法决定“池中的哪一个”。把二者混为一谈,会误以为更换算法就能解决跨地域成本、版本隔离或租户路由问题。

    2、转发可以是改包,也可以是代理

    四层直通方案可能只改写目标地址并维护连接状态,后端直接或经负载均衡器返回;全代理方案终止客户端连接,再建立一条到后端的新连接。七层方案通常必须解析应用协议,因此天然更接近全代理,但 TLS 直通、SNI 路由和 QUIC 等场景会形成更多组合。

    需要特别强调:四层不等于一定“无连接”,七层也不等于一定“每个请求都新建连接”。现代代理会复用上游连接池,四层 TCP 代理同样维护双向连接;真正差异在于可观察的协议语义和可执行的策略粒度。

    三、负载均衡的实现方式:能力分布在哪里

    (一)入口侧的三类实现

    1、DNS 与全局流量调度

    DNS 可以为同一域名返回多个地址,或根据地域、延迟、权重和健康状态返回不同区域入口。它覆盖范围大、适合跨地域,但缓存和 TTL 使切换不可能绝对即时;递归解析器的位置也不总能准确代表终端用户。DNS 更适合选择“区域或入口集群”,区域内通常还需要四层或七层负载均衡。

    Anycast 则让多个地点宣告同一个 IP,网络路由把用户带到拓扑上较近的接入点。它擅长全局接入和故障绕行,但 BGP 收敛、路径变化与有状态连接迁移需要额外设计。DNS 与 Anycast解决的是大尺度入口选择,不替代应用实例级调度。

    2、四层网络负载均衡

    四层负载均衡主要依据源/目的 IP、源/目的端口和传输协议形成的流标识进行选择。实现可以位于专用设备、云网络、Linux IPVS、eBPF 程序或用户态高性能转发器。它适合 TCP、UDP 和非 HTTP 协议,也适合需要高吞吐、低额外时延或 TLS 直通的场景。

    典型转发模式包括:

    • NAT/全 NAT:入口改写地址,返回流量通常也经过入口,部署直接但入口承受双向流量;

    • 直接路由(DR/DSR):请求经调度器,响应由后端直接返回,减轻入口回程压力,但网络配置更复杂;

    • 隧道转发:将请求封装送到远端后端,可跨三层网络,增加封装开销;

    • 四层代理:分别终止前后端 TCP 连接,获得更强连接控制,但数据都经过代理。

    3、七层反向代理

    七层负载均衡解析 HTTP/HTTPS、gRPC 或其他应用协议,可以按域名、路径、方法、Header、Cookie、查询参数或请求内容路由。它能够完成 TLS 终止、连接复用、压缩、缓存、认证、WAF、重写、流量镜像和细粒度指标。

    这类能力的代价是更高的 CPU 与内存消耗、更复杂的配置,以及成为协议升级和安全边界的一部分。七层代理必须正确处理请求走私、Header 规范化、超时、主体大小、流式响应和 WebSocket 等细节;它的价值不是“功能越多越好”,而是把确有必要的应用语义控制集中在合适边界。

    生产系统往往同时使用 DNS/Anycast、区域四层入口、七层网关和服务间调度,各层解决不同尺度的问题。

    (二)服务侧的三类实现

    1、客户端负载均衡

    客户端从注册中心获得后端列表,在本地执行算法并直接连接实例。优点是少一跳、策略可贴近调用方、没有集中代理吞吐瓶颈;缺点是每种语言都要维护库,策略升级与证书管理困难,错误实现会在整个调用面扩散。

    客户端负载均衡常见于 RPC 框架和微服务。为了避免每个调用方都实时拉取全量状态,通常需要本地缓存、增量更新、过期保护和失败回退。客户端还要承担重试预算、连接池和异常实例剔除,否则“去掉中间代理”只是把复杂度分散到更多进程。

    2、服务网格与边车/节点代理

    服务网格把客户端侧能力下沉到边车、节点代理或内核数据面,通过统一控制面下发服务发现、mTLS、路由、熔断和可观测策略。它兼顾多语言一致性与调用侧就近决策,但引入新的资源开销、配置层次和故障模式。

    边车模式每个工作负载旁都有代理,隔离性好、升级粒度细;节点代理或无边车模式共享更多数据面资源,减少实例数量,却要求更谨慎的多租户隔离。无论形态如何,服务网格都不消除负载均衡,只是改变负载均衡能力的部署位置。

    3、服务端分派与工作队列

    并非所有负载都以同步网络请求出现。任务队列、消息消费者、批处理调度器同样在分配工作。生产者把任务写入队列,多个消费者竞争或按分区领取,确认机制决定失败后是否重投。这里的“算法”可能是分区哈希、消费者组再均衡、优先级队列或工作窃取。

    把网络负载均衡与任务调度放在同一框架下理解,可以看到共同问题:候选工作者发现、能力差异、任务粘性、失败重试、背压、顺序性和重复执行。不同之处是同步请求更敏感于即时尾时延,队列系统更关注积压、吞吐和至少一次/至多一次语义。

    (三)单层方案与组合方案

    1、为什么生产系统常常多层并存

    全局调度要看地域和灾备,区域入口要扛高连接速率,应用网关要识别 HTTP 语义,服务间调用要靠本地发现。让一个组件同时承担全部职责,会把配置、容量和故障域集中到一点。多层设计允许每层使用最合适的数据和算法。

    但层数不是越多越好。每增加一层,就增加一次排队、一次超时配置、一次日志关联和一个潜在故障点。设计时应给每层一个明确职责,并画出完整时延预算。例如外层超时必须大于内层超时与重试总和,否则外层已放弃,内层仍在消耗资源,形成“幽灵请求”。

    2、旁路与降级路径必须提前设计

    入口负载均衡器本身也需要高可用:可通过多实例、Anycast、ECMP、主备 VIP、云托管服务或客户端多地址实现。控制面失联时数据面是否继续服务、证书过期前是否能更新、配置回滚是否独立于主控制面,都是必要问题。

    一个常被忽略的原则是:不要把所有恢复动作都依赖于同一个故障域。 如果配置平台、身份系统和流量入口共用同一数据库,数据库故障时既影响业务,又阻止运维切流。关键降级路径应尽量简单、预置并经过演练。

    四、负载均衡算法:从“分得平均”到“适应系统”

    (一)静态算法:低成本建立基本秩序

    1、轮询与加权轮询

    1.1 普通轮询

    轮询(Round Robin)按固定顺序依次选择健康后端:A、B、C、A、B、C。其状态量很小,选择开销近似常数,适合能力相近、请求成本接近且连接寿命较短的实例池。NGINX 的 HTTP 上游在未指定其他方法时即采用轮询。

    轮询的隐含假设是“下一份工作成本与前一份差不多”。一旦出现慢请求、长连接或异构实例,后端收到的请求数相同,当前未完成工作却可能差异很大。轮询也不感知某台服务器刚刚经历抖动,除非健康检查先将其移出。

    1.2 加权轮询

    加权轮询(Weighted Round Robin)按能力比例分配。例如 A、B、C 权重为 3:1:1,在足够长窗口内,A 约接收五分之三的请求。权重可以表示机型能力、成本偏好、版本灰度或区域优先级。

    权重不是“CPU 核数”的简单映射。真实吞吐会受内存、缓存命中、I/O 和下游配额影响,应以代表性压测和生产观测校准。权重调整也应渐进;一次把新实例权重设满,可能让未预热缓存和连接池瞬间过载。

    “平滑加权轮询”会维护每个节点的当前权重,使短窗口内也尽量均匀,避免简单复制权重序列产生连续突发。它适合请求成本较稳定的异构池,是工程中很常见的默认选择。

    2、随机与加权随机

    随机算法从健康集合中随机选一个节点。单次结果不可预测,但大样本下趋近均匀;它不需要全局游标,多个负载均衡实例也不必同步轮询位置。加权随机按权重构造概率分布,能表达能力差异。

    随机的波动在小流量池中更明显,连续命中同一后端完全可能发生。它的优势是实现简单、扩展性好,并能减少某些由固定顺序与节点故障共同造成的偏差。工程上还常把随机作为采样步骤,与最少请求组合成 P2C。

    普通轮询追求次数相等,加权轮询追求比例匹配,随机算法在长窗口趋近目标但短窗口存在波动。

    (二)动态算法:用实时状态修正分配

    1、最少连接与最少请求

    1.1 最少连接

    最少连接(Least Connections)把新连接交给当前活动连接最少的后端,常见加权形式可理解为选择 active_connections / weight 最小者。它适合连接持续时间差异较大的 TCP 服务、WebSocket 或长轮询,因为慢连接会让节点计数保持较高,从而减少后续分配。

    不过,连接数不等于工作量。一个空闲 WebSocket 与一个持续传输大文件的连接都只计 1;HTTP/2 一个连接可承载许多并发流。若代理复用到后端的连接池,前端连接数也未必反映后端请求数。选用此算法前,必须确认“计数对象”与实际资源消耗相关。

    1.2 最少未完成请求

    七层代理可以统计活动请求而非 TCP 连接,选择未完成请求较少的节点。对于 HTTP/2、gRPC 等多路复用协议,这通常比连接数更贴近负载。Envoy 的最少请求策略在等权节点中默认使用“随机抽取两个候选,再选活动请求更少者”的近似方法,也就是 Power of Two Choices。

    2、最短响应时间与自适应权重

    2.1 延迟感知

    最短响应时间算法根据历史延迟选择后端,通常用指数加权移动平均(EWMA)平滑瞬时噪声。可将一个简化得分写成:

    score(i) = α × 延迟 EWMA + β × 当前排队 + γ × 错误惩罚。

    选择得分更低的节点,能把流量从持续变慢的实例移开。但如果对短时变化反应过快,多个调度器会同时追逐“看起来最快”的节点,随后又同时离开,产生羊群效应。平滑窗口、随机采样、最小流量保障和权重变化速率限制,是稳定控制的重要组成。

    2.2 后端主动上报

    仅从代理侧观察响应时间,无法区分网络、应用和下游依赖的贡献。更高级的自适应算法允许后端上报 CPU 利用率、队列深度、请求成本、每秒错误数等指标,再计算动态权重。Envoy 的客户端加权轮询扩展可结合 ORCA 负载报告调整端点权重,体现了“让服务报告真实工作量”的方向。

    主动上报也有风险:指标可能延迟、丢失或被错误实现污染。控制逻辑应为缺失和异常值设置保守回退,避免单个错误指标把全部流量导向错误节点。自适应算法不是越灵敏越好,而是在可观测性、稳定性与收益之间取平衡。

    3、P2C:在效果与复杂度之间折中

    P2C(Power of Two Choices)随机选取两个健康节点,比较活动请求、连接数或综合负载,选择更轻的一个。它避免每次遍历全部 N 个节点,选择复杂度近似 O(1),却能显著降低纯随机造成的热点。

    其直觉是:随机一次可能抽到忙节点,随机两次同时抽到忙节点的概率明显更低。把抽样数增加到 3 或更多仍有收益,但边际改善下降、读取状态成本上升。P2C 特别适合后端数量大、调度器并发高且状态略有延迟的系统。

    动态算法并非寻找绝对“最闲”节点,而是在状态成本、信息新鲜度和调度稳定性之间取舍。

    (三)哈希算法:用稳定映射换取局部性

    1、普通哈希与会话粘性

    普通哈希根据键 k 计算 h(k) mod N,将同一键映射到固定后端。键可以是源 IP、Cookie、用户 ID、URL、对象键或租户 ID。它无需共享会话表,能提高本地缓存命中、保持协议状态或让同一对象落到同一分片。

    问题在于 N 变化时,大量键会重新映射。增加或删除一台后端会引起广泛缓存失效和会话漂移,变更瞬间的回源流量可能比日常流量大得多。使用源 IP 作为键还有两个问题:大量用户可能共享 NAT 出口形成热点;移动网络地址变化会破坏粘性。

    2、一致性哈希

    一致性哈希把后端和请求键映射到一个环,请求沿顺时针找到首个节点。节点变化时,理论上主要影响邻近区间,而不是重排全部键。为改善分布,每个物理节点通常对应多个虚拟节点,数量可与权重相关。

    当 N 个等权后端中增加或移除一个节点时,理想情况下约 1/N 的键需要迁移;实际比例取决于虚拟节点数量和散列质量。一致性哈希适合缓存、状态分片和希望减少重映射的场景,但不能自动解决热点键:一个超级热门对象仍可能压垮其负责节点,需要复制热点、分层缓存或对热键单独治理。

    3、Rendezvous 与 Maglev

    Rendezvous(最高随机权重)哈希为每个“键—节点”组合计算得分,选择最高者。它概念简洁,节点变化时映射稳定,适合候选集合不太大或可进行优化的场景。

    Maglev 预先构建查找表,请求哈希后 O(1) 访问表项,兼顾高速查找与后端变化时的有限扰动,最初用于大规模软件网络负载均衡。Envoy 等代理也提供 Maglev 负载均衡策略。与环哈希相比,Maglev 通常查找更快,但表大小、权重表达和节点变化时的重映射特性需要根据实现评估。

    普通取模在节点数变化后大范围重映射;一致性哈希将变化限制在环上的局部区间。

    (四)算法选择不能脱离工作负载

    1、算法比较表

    算法主要依据优点典型局限更适合的场景
    轮询 请求/连接顺序 简单、稳定、开销低 不感知成本和实时负载 同构实例、短请求、成本相近
    加权轮询 静态权重 支持异构容量和灰度 权重需校准,难跟随突变 不同机型、版本分流
    随机 概率 无全局游标、易水平扩展 小样本波动、可能连击 大规模同构池
    最少连接 活动连接数 适应长短连接差异 连接不一定代表工作量 TCP 长连接、WebSocket
    最少请求/P2C 活动请求或采样负载 效果好、扩展性高 依赖状态统计 HTTP/2、RPC、大后端池
    最短时间/EWMA 历史延迟与在途量 能绕开慢节点 易受噪声和羊群效应影响 时延差异明显的服务
    普通哈希 键与节点数 粘性强、实现简单 扩缩容时大范围重映射 节点集合稳定的小型池
    一致性哈希 哈希环/虚拟节点 节点变化扰动较小 热键、环参数与分布复杂 缓存、状态分片
    Maglev 预计算查找表 高速、映射相对稳定 表构建和权重细节依实现 高吞吐网络与代理
    自适应权重 利用率、错误、成本报告 贴近真实能力 指标延迟与控制稳定性难 成熟平台、大规模异构池

    2、一个实用选择顺序

    工程上可以从最简单且可验证的算法开始:

  • 实例同构、请求短且成本接近:轮询;

  • 实例能力不同:加权轮询;

  • 连接寿命差异大:加权最少连接;

  • 多路复用、请求成本差异明显:最少请求或 P2C;

  • 必须保持缓存/会话局部性:一致性哈希或 Maglev;

  • 已有可靠负载指标与控制经验:再考虑自适应权重。

  • 算法升级前应先确认健康检查、超时、连接池和容量是否正确。很多“轮询不均”实际上是慢节点、DNS 解析、连接复用、长连接或热点键造成的;换一个复杂算法可能掩盖症状,却没有消除根因。

    五、四层负载均衡:以连接和数据包为中心

    (一)四层究竟能看见什么

    1、五元组与连接一致性

    典型四层调度使用源 IP、源端口、目的 IP、目的端口和传输协议组成五元组,或使用其中一部分做哈希。TCP 是面向连接的可靠字节流,负载均衡器必须让同一连接的双向包命中一致的后端和状态。新连接可以重新选择,已建立连接通常不能无缝搬迁。

    UDP 没有 TCP 式握手和关闭,四层设备常通过五元组加空闲超时模拟“会话”。如果客户端重绑端口、NAT 映射变化或 QUIC 迁移连接,简单五元组可能失效。支持 QUIC Connection ID 的负载均衡方案可以降低地址变化影响,但那已超出最朴素的 UDP 哈希。

    2、TLS 直通时看不到 HTTP 内容

    若四层负载均衡器把 TLS 流量原样转发,HTTP 方法、路径、Header、Cookie 和响应码都被加密,调度器无法按 URL 路由,也无法直接执行 WAF。它可以按端口和 IP 分池;某些实现还能在不解密应用数据的情况下读取 TLS ClientHello 中的 SNI 进行有限路由,但加密 ClientHello 的演进会进一步约束可见性。

    这正是四层高性能与低语义之间的交换:少解析、少改写、协议覆盖广,但无法基于应用含义做精细决策。

    (二)四层的常见数据路径

    1、NAT:易理解但要规划回程

    客户端访问 VIP,调度器把目标地址改为真实服务器地址,并记录连接映射;响应返回时再做反向转换。优点是后端改造少、拓扑直观,缺点是双向流量经过调度器时,出口带宽和状态表都要按峰值规划。

    端口耗尽也是代理/NAT 架构的实际约束。若到后端的连接都使用少量源 IP,源端口空间、TIME_WAIT、连接跟踪表和 SNAT 分片可能比 CPU 更早成为瓶颈。容量评估必须包含“每秒新连接”和“并发连接”,不能只看 Gbit/s。

    2、直接路由与直接服务器返回

    DSR/DR 模式让调度器只处理入站,请求到达选定后端后,响应由后端直接发给客户端。对于响应远大于请求的下载、视频或缓存服务,可以显著减轻入口回程负担。

    代价是网络和主机配置更复杂:后端要正确处理 VIP,避免错误 ARP 响应;路径 MTU、反向路径过滤、安全策略和可观测性都需要配套。因为响应绕过调度器,入口无法直接看到完整双向指标,也难以在回程执行统一处理。

    3、四层全代理

    四层代理在客户端侧接受 TCP,再与后端建立独立 TCP。它可以控制连接超时、PROXY Protocol、TLS 透传、连接限额和上游重连,并隔离前后端网络细节。代价是代理要维护双边状态和缓冲区,所有字节经过用户态或代理数据面。

    三种四层路径的核心差异在于谁终止连接、谁处理返回流量,以及入口需要保存多少状态。

    (三)四层的优势与边界

    1、优势

    • 协议通用,适合 TCP、UDP、数据库、消息队列、邮件、游戏和自定义协议;

    • 数据路径短,易于实现高吞吐、低额外时延和大并发;

    • 可保持端到端 TLS,让证书和解密边界位于后端;

    • 直通方案可以保留客户端源地址,并减少代理层内容处理。

    2、边界

    • 无法依据 URL、Cookie、HTTP 方法或业务身份路由;

    • 健康检查若仅连端口,容易把应用级故障判为健康;

    • 连接级分配在 HTTP/2、gRPC 长连接下可能出现少量连接承载大量请求;

    • 无法在不终止协议的情况下完成缓存、压缩、Header 改写和 WAF;

    • 有状态转发表、SNAT 端口、连接同步和长连接排空都需要工程治理。

    六、七层负载均衡:以请求语义为中心

    (一)七层代理如何处理一条请求

    1、终止、解析、匹配、转发

    典型 HTTPS 七层路径是:客户端与代理完成 TCP/TLS 或 QUIC/TLS 握手;代理解密并解析 HTTP;根据 Host、路径、方法、Header、Cookie 或身份匹配路由;在目标池中选择后端;从连接池取得或建立上游连接;转发请求并处理响应。

    这意味着代理同时处在两个连接域:客户端到代理,以及代理到后端。两侧可以使用不同协议版本,例如客户端使用 HTTP/3,代理到后端使用 HTTP/2;也可以在入口终止公网证书,再用内部 mTLS 连接后端。协议转换带来灵活性,也使代理成为必须严格测试的语义边界。

    2、连接池改变了“连接数”的含义

    七层代理通常复用上游连接,减少握手和慢启动成本。一个客户端连接可以产生多个请求,多个客户端请求也可能复用少量上游连接。于是,客户端连接数、代理活动请求数和后端连接数是三个不同指标。

    HTTP/2 和 HTTP/3 支持多路复用,单条连接可承载多个并发流。如果只按建立连接时做一次后端选择,某条长寿命连接可能让后端长期偏热。七层代理按请求或流调度,更有机会获得细粒度平衡,但流式 RPC 的持续时间仍需要纳入在途量。

    七层入口在应用语义上依次完成安全终止、路由匹配、后端选择、连接复用和响应治理。

    (二)七层提供的核心能力

    1、内容路由与多服务复用

    同一个入口可以把 api.example.com 路由到 API 池,把 static.example.com 路由到静态池;也可以将 /orders、/users、/search 分给不同服务。基于 Header 或 Cookie 的规则可用于租户隔离、设备类型、实验分组和版本灰度。

    路由规则应保持可解释。大量正则和交叉条件会形成“规则阴影”:前面的宽泛规则吞掉后面的精确规则,变更难以推演。生产平台应提供静态冲突检查、规则命中统计和请求级路由原因记录。

    2、TLS、安全与协议规范化

    集中 TLS 终止便于证书轮换、协议版本控制和硬件加速;WAF、Bot 管理、身份验证和速率限制也可在应用前执行。代理还能规范 Host、X-Forwarded-For、Forwarded 和请求长度,避免后端各自解释不一致。

    但“入口已做安全”不能成为后端完全信任任意 Header 的理由。只有来自可信代理链的转发头才应被接受,代理与后端之间需要网络隔离或 mTLS,外部客户端提供的同名头应覆盖或清理。多层代理还要明确定义谁追加、谁保留以及如何计算真实客户端地址。

    3、可靠性与交付治理

    七层代理可执行超时、有限重试、断路、异常实例剔除、请求镜像、权重分流和故障转移。它还能按路由统计状态码、延迟、字节量和上游失败原因,为 SLO 提供更接近业务的信号。

    需要克制的是重试。对 GET 等幂等请求,连接建立失败时重试通常安全;对支付、下单等非幂等操作,若后端已执行但响应丢失,盲目重试会产生重复副作用。即使幂等,重试也会放大负载。必须设定每请求次数、全局重试预算、退避和抖动,并把原始请求与重试分开观测。

    (三)七层的成本与风险

    1、计算与延迟成本

    TLS 握手、加解密、HTTP 解析、规则匹配、日志和安全检查都需要 CPU 与内存。连接池和缓冲区会占用文件描述符及内存,压缩大响应可能成为 CPU 热点。高并发下,尾时延更容易受到垃圾回收、事件循环阻塞、锁竞争或日志 I/O 影响。

    正确做法不是简单认定七层“慢”,而是按真实请求大小、连接复用率、协议版本、证书算法和规则复杂度压测。托管服务、专用加速、会话复用和 TLS 1.3 可以降低成本,但无法免除容量验证。

    2、语义错误与集中风险

    代理必须正确处理分块编码、Content-Length、连接升级、WebSocket、流式响应、gRPC 状态、Header 大小和不同 HTTP 版本之间的转换。前后端对消息边界解释不一致可能引发请求走私等安全问题。

    七层配置又常被多个团队共享,一条错误路由即可影响多个服务。应把配置视为代码:使用模式校验、单元测试、影子评估、分批下发、自动回滚与审计。控制面推送失败时保留最近有效版本,避免“空配置”比旧配置更危险。

    七、四层与七层的区别:不是简单的性能二选一

    (一)核心差异对照

    1、能力矩阵

    维度四层负载均衡七层负载均衡
    主要观察对象 IP、端口、TCP/UDP、连接/流 HTTP/HTTPS、gRPC 等请求语义
    常见选择粒度 新连接或 UDP 会话 请求、流或应用会话
    路由条件 地址、端口、协议、有限 TLS 元数据 Host、路径、方法、Header、Cookie、身份等
    TLS 处理 常见为透传,也可做 TCP/TLS 代理 通常终止 TLS 后解析应用协议
    协议覆盖 广,适合非 HTTP 和自定义协议 取决于代理支持的应用协议
    典型优势 高吞吐、低额外时延、源地址保留 精细路由、安全、观测、发布治理
    主要资源 转发表、连接状态、包处理、带宽 CPU、内存、连接池、解析与加密
    健康检查深度 TCP/字节探测为主,也可独立做 HTTP 可按 HTTP/gRPC 语义检查
    会话保持 源 IP/五元组哈希、连接天然粘性 Cookie、Header、用户键、一致性哈希
    常见风险 状态表耗尽、连接倾斜、回程拓扑复杂 规则错误、协议歧义、重试放大、证书风险
    典型产品形态 IPVS、eBPF、NLB、网络设备 NGINX、HAProxy、Envoy、ALB、应用网关

    2、“第几层”是工程简称,不是完整架构描述

    OSI 分层帮助讨论可见信息,但真实产品经常跨层。例如网络负载均衡器可能终止 TLS,七层网关底层仍要处理 TCP/QUIC;SNI 路由介于纯传输与完整 HTTP 解析之间;HTTP/3 基于 QUIC,而 QUIC运行在 UDP 之上。只看产品名称中的 L4/L7,不足以判断源地址、连接终止、回程路径和协议支持。

    选型时应具体询问:

    • 客户端连接在哪里终止?

    • 负载均衡器能读取哪些字段?

    • 调度发生在连接、请求还是流的粒度?

    • 响应是否经过同一数据面?

    • 客户端真实地址如何传递?

    • 健康检查验证到哪一层?

    • 故障时已建立连接如何处理?

    四层关注连接与通用协议覆盖,七层关注请求语义与治理;二者经常在一条链路中协同。

    (二)性能差异应怎样理解

    1、四层通常更轻,但不是无成本

    四层无需完整解析 HTTP,直通实现可在内核或网卡附近高速转发,通常更容易达到高包速和大连接规模。不过 NAT 状态、连接跟踪、哈希表、跨核同步、SNAT 端口、DDoS 防护和回程带宽仍会成为瓶颈。小包场景看包每秒,大包场景看带宽,新建连接场景看握手和状态创建,不能只用一个 QPS 数字评价。

    2、七层增加处理,也可能改善端到端性能

    七层代理有解析和加密成本,却能通过 TLS 会话复用、上游连接池、缓存、压缩、就近路由和慢后端规避降低端到端时延。若没有代理,每个客户端都与后端频繁建连,后端可能承担更高握手与连接管理成本。

    所以正确比较对象是“整个请求路径在目标 SLO 下的资源与时延”,不是单独比较一个组件的微基准。对 1 KB API、1 GB 下载、数小时 WebSocket 和高频 UDP 包,答案会完全不同。

    (三)什么时候组合使用

    1、常见组合:四层入口加七层网关

    四层入口提供稳定 VIP、DDoS 衔接、跨可用区分流和大规模连接接入;七层网关负责 TLS、HTTP 路由、WAF、限流和灰度。这样既保留高性能网络入口,也把应用语义集中在网关层。

    组合时需要避免重复功能冲突。例如两层都重试会让一次失败指数放大,两层都做健康检查却检查不同路径会产生状态分歧,两层空闲超时不一致会让内层先关闭而外层仍复用连接。必须有一张“每层职责与超时预算表”。

    2、服务间再使用客户端或网格调度

    进入应用后,服务 A 调用服务 B 可以通过客户端负载均衡或服务网格就近选择端点。外部网关不应承担全部内部服务发现,否则东西向流量绕行入口,增加时延和故障耦合。

    多层架构的理想状态是:外层做粗粒度、稳定且跨域的选择;内层做细粒度、实时且贴近服务的选择。每层都只使用它真正掌握的数据。

    八、健康检查、会话与失败治理

    (一)健康检查是一台状态机

    1、阈值、迟滞与抖动

    若一次失败就摘除、一次成功就恢复,短暂网络抖动会让实例在健康与异常之间频繁跳变,流量不断重新分配。更稳健的做法是设置连续失败阈值、连续成功阈值和不同的进入/退出条件,也就是迟滞。

    例如每 5 秒检查一次,连续 3 次失败才摘除,最坏发现时间约为 15 秒加超时;连续 2 次成功恢复,则最少还需约 10 秒。缩短间隔能更快发现故障,却会增加探测流量和误报概率。参数应由允许故障暴露时间、实例数量和探针成本共同决定。

    2、排空、预热与慢启动

    计划下线不应与故障摘除相同。排空状态停止新请求,同时允许已有连接或请求在截止时间内完成;超过期限再强制关闭。对 WebSocket、流式 RPC 和大文件传输,需要业务定义可接受的最大排空时间。

    恢复节点也不应立即满载。冷缓存、JIT、连接池和数据加载会使刚启动实例更慢。慢启动把权重从小到大逐步提升,并用错误率和尾时延决定是否继续。这样可以避免“刚恢复就再次被打挂”的循环。

    健康管理需要迟滞、排空和慢启动;简单的健康/异常二值切换不足以支撑生产流量。

    (二)会话保持是权衡,不是默认答案

    1、为什么需要粘性

    旧式应用可能把登录会话、购物车或临时文件保存在本机内存,同一用户必须回到同一实例。缓存局部性、长事务、自定义协议状态也可能需要稳定映射。常见方式包括源 IP 哈希、负载均衡器 Cookie、应用 Cookie、Header/用户 ID 哈希和一致性哈希。

    2、粘性带来的代价

    粘性减少调度自由,用户分布不均会形成热点;节点故障时,会话仍会丢失或迁移;扩缩容时映射变化,缓存和状态会重建。源 IP 粘性在 NAT、代理和移动网络下尤其不可靠,Cookie 粘性又只适用于理解 HTTP 的代理。

    更具弹性的架构是把必要状态外置到共享存储,或使用可复制、有明确一致性模型的状态服务,使任意健康实例都能处理请求。粘性可以作为性能优化或迁移手段,但不宜成为高可用的唯一前提。

    (三)超时、重试、熔断和背压要协同

    1、超时是资源预算

    连接超时、TLS 握手超时、请求头超时、整体请求超时、上游空闲超时和连接最大寿命含义不同。超时过长会占用线程、连接和内存,过短则把正常慢请求误判为失败。外层超时必须覆盖内层可能发生的处理与重试,但也要小于用户或上游调用方的总期限。

    2、重试必须有预算

    如果一次请求最多重试 2 次,理论上后端工作量可变为原来的 3 倍。故障时更多请求同时失败,重试恰好发生在容量最少的时候。安全策略包括:仅对明确可重放的操作重试;只在部分错误类型上重试;采用指数退避和随机抖动;设置全局重试预算;尊重调用方剩余期限;优先重试到不同后端。

    3、熔断与背压防止扩散

    熔断限制某个后端池的并发请求、连接、等待队列和重试数量,达到阈值后快速失败,保护系统不被无限排队拖垮。背压让上游根据下游能力减速,限流则在入口拒绝超出预算的请求。快速失败可能降低短期成功率,却能保住核心流量和恢复能力。

    慢后端引发超时,超时触发重试,重试进一步增加排队;预算、熔断和背压用来打断正反馈。

    九、生产实现:从需求到验证的完整方法

    (一)先定义目标与流量画像

    1、回答七个基础问题

    在选产品和算法之前,先明确:

  • 协议是什么:HTTP/1.1、HTTP/2、HTTP/3、gRPC、TCP、UDP 还是自定义协议?

  • 流量特征是什么:QPS、每秒新连接、并发、包速、带宽、请求/响应大小如何分布?

  • 连接寿命多长:毫秒级短请求、分钟级流式传输还是小时级长连接?

  • 是否需要应用语义:按域名、路径、身份、租户或版本路由吗?

  • 状态在哪里:无状态、共享状态、本地会话还是分片缓存?

  • 故障目标是什么:允许多快发现、允许丢多少连接、单区故障后要保留多少容量?

  • 安全与合规边界在哪里:TLS 在哪里终止,日志能否包含 Header,流量是否允许跨区?

  • 这些答案决定架构上限。算法只是其中一个旋钮。

    2、用分布而不是平均值描述负载

    平均响应 20 ms 可能掩盖 P99 为 2 秒;平均响应体 10 KB 可能掩盖少量 1 GB 下载;平均连接 5 秒可能同时包含大量短连接和少量永久连接。容量与排队受尾部分布支配,压测必须保留真实比例。

    建议至少建立:请求类型占比、时延分位数、连接寿命分布、请求/响应大小分布、每客户端并发、热点键集中度、区域来源和失败类型分布。没有流量画像,就无法判断连接数、请求数还是字节数才是合适的均衡信号。

    (二)设计数据面、控制面与故障域

    1、数据面容量与冗余

    数据面至少跨两个故障域部署,单个实例或单个可用区失效后仍能承载目标流量。若使用主备模式,要验证切换时间和连接影响;若使用多活,要验证流量是否真的均匀进入所有实例,状态是否需要同步。

    容量指标应覆盖:

    • 包每秒、比特每秒;

    • 每秒新连接、并发连接;

    • TLS 每秒握手和会话复用率;

    • 活动请求、队列长度;

    • CPU、内存、文件描述符、端口和连接跟踪表;

    • 配置规模、证书数量、路由规则匹配成本。

    2、控制面安全与回滚

    配置应经过模式校验、引用完整性检查、路由冲突测试和容量保护。例如不能把生产池全部权重设为 0,不能引用不存在的证书,不能把健康检查改成必然失败的路径。下发采用分批和确认机制,数据面只切换到完整有效版本。

    控制面还要保留最近有效配置、版本历史和一键回滚。若新配置导致错误率上升,可由自动化指标触发停止或回退,但自动回滚本身也需要防抖与权限边界。

    3、故障域优先于算法

    若三台后端都在同一机架,轮询再均匀也无法抵御机架故障。候选集合应先按区域、可用区、机架、集群或电源域分组,再做分层调度。通常优先使用本地健康容量,容量不足或故障时才跨区,避免日常跨区成本与延迟。

    (三)配置示例与实现要点

    1、NGINX 四层 TCP 示例

    以下示例使用 stream 模块转发数据库代理端口,并采用最少连接。真实生产还需配置日志、主动健康检查能力(取决于版本/发行形态)、连接限额与高可用入口。

    stream {
    upstream db_tcp_pool {
    least_conn;
    server 10.20.1.11:5432 weight=2 max_fails=3 fail_timeout=10s;
    server 10.20.1.12:5432 weight=2 max_fails=3 fail_timeout=10s;
    server 10.20.1.13:5432 backup;
    }

    server {
    listen 5432;
    proxy_connect_timeout 2s;
    proxy_timeout 60s;
    proxy_pass db_tcp_pool;
    }
    }

    这里的选择发生在 TCP 连接建立阶段。应用连接池如果长期保持少量连接,新增后端不会自动接到既有连接;需要设置合理连接寿命或由客户端逐步重建。

    2、NGINX 七层 HTTP 示例

    http {
    upstream api_pool {
    least_conn;
    server 10.30.1.21:8080 weight=2 max_fails=3 fail_timeout=10s;
    server 10.30.1.22:8080 weight=2 max_fails=3 fail_timeout=10s;
    keepalive 128;
    }

    server {
    listen 443 ssl;
    server_name api.example.com;

    location /v1/orders/ {
    proxy_connect_timeout 1s;
    proxy_read_timeout 15s;
    proxy_set_header Host $host;
    proxy_set_header X-Request-ID $request_id;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_pass http://api_pool;
    }
    }
    }

    七层配置可以按路径选择池,并复用上游连接。生产环境应明确幂等性后再启用重试,设置请求体和 Header 限制,保护真实客户端地址链,并为 TLS 证书轮换设计自动化。

    3、Kubernetes Service 与网关

    Kubernetes Service 为一组 Pod 提供稳定虚拟地址,kube-proxy 或其他数据面把流量转到 EndpointSlice 中的端点;Ingress/Gateway API 实现更丰富的 HTTP/TCP 路由。需要区分:

    • Service 的 ClusterIP/LoadBalancer 解决服务暴露与端点转发;

    • externalTrafficPolicy、internalTrafficPolicy 和流量分布偏好影响本地性与源地址;

    • sessionAffinity 可按客户端 IP 提供有限粘性;

    • Gateway API 的 Listener、Route 与 BackendRef 描述七层或多协议路由;

    • 云 LoadBalancer、集群入口控制器与 Service 数据面可能形成多层路径。

    不要只看 YAML 是否创建成功,要从客户端实际追踪 DNS、云入口、节点转发、网关、Service 和 Pod 的每一跳。

    (四)测试要覆盖正常与异常

    1、基准与容量测试

    先测单实例在目标 SLO 下的稳定容量,再测集群和负载均衡器,比较扩展效率。压测要保持真实连接复用、请求比例、响应大小和 TLS 行为。观察 P50/P95/P99、错误率、每后端分布、队列、CPU、内存、包速和新连接速率。

    不要只跑到“机器 100%”才算峰值。SLO 被突破、队列持续增长或错误率开始上升的位置,就是有效容量边界。压测报告应给出饱和前后的性能曲线,而不是一个孤立的最大 QPS。

    2、故障注入

    至少验证:

    • 单实例进程退出、端口拒绝和应用返回错误;

    • 网络丢包、延迟、半开连接和 DNS/服务发现延迟;

    • 单可用区失效;

    • 健康检查误报与控制面失联;

    • 新实例冷启动、旧实例排空;

    • 证书更新失败、配置回滚;

    • 后端全部异常时的失败模式;

    • 重试、熔断和限流在高压下是否按预期工作。

    故障测试的关键不是“最终恢复”,而是记录发现时间、摘除时间、用户错误、连接损失、剩余容量和恢复波动。

    3、分布正确性测试

    对轮询和随机算法,不能用几十个请求下结论;应在足够样本下比较实际占比与目标权重,同时分开统计新连接和请求。对哈希算法,要测试键分布、热点、节点增删后的迁移比例。对动态算法,要注入慢节点,观察流量转移速度与是否发生振荡。

    十、可观测性:证明流量真的被均衡

    (一)指标要能回答“谁慢、为什么慢”

    1、入口指标

    入口至少记录接收连接/请求、接受失败、TLS 握手、活动连接、字节吞吐、响应状态、总体时延、上游连接时延、首字节时间、重试次数、限流和熔断拒绝。四层系统还要关注连接状态、转发表使用率、SNAT 端口、丢包、重传和无后端可选次数。

    2、后端维度

    所有核心指标都应能按后端、池、路由、可用区和版本拆分。集群平均成功率 99.9% 可能掩盖某节点 20% 错误,因为它只接到少量流量。每后端的活动请求、连接、QPS、延迟和错误是判断算法效果的基本证据。

    3、分布偏斜指标

    可以用最大/最小负载比、标准差、变异系数或 Gini 系数描述分配偏斜,但必须与权重归一化。更直接的方法是计算每个节点“实际份额 − 期望份额”,并同时观察节点资源与请求成本。对于动态算法,短期偏斜可能是正确行为,因为它在避开慢节点。

    (二)日志、追踪与配置版本

    1、访问日志需要上下游关联

    日志建议包含请求 ID、路由名称、选中后端、连接复用情况、重试次数、各阶段耗时、最终状态和配置版本。敏感 Header、Cookie 和个人信息应按最小必要原则脱敏或不记录。

    2、分布式追踪揭示排队位置

    代理跨度可以记录 DNS、连接、TLS、上游排队、后端处理和响应传输。若总时延升高但后端处理不变,问题可能在连接池或入口排队;若单个后端跨度升高,算法或健康检查应介入。追踪采样在故障期间可动态提高,但要控制成本。

    3、配置版本必须进入遥测

    没有配置版本,无法判断错误峰值是否由一次路由变更引起。指标、日志和事件都应标注数据面当前版本,控制面记录谁在何时变更了什么、哪些实例已接收。这样才能把“流量异常”与“策略变化”建立因果线索。

    入口结果、后端分布和控制面版本三类证据相互印证,才能判断负载均衡是否有效。

    十一、典型场景如何选择

    (一)面向公网的 Web 与 API

    1、推荐思路

    通常需要七层能力:TLS 终止、域名/路径路由、WAF、认证、限流、可观测和灰度。大规模公网接入可在前面增加 Anycast/CDN 或四层网络入口,区域内由七层网关分发到应用。

    算法可从加权轮询或最少请求开始。短 API 且实例同构时轮询足够;请求耗时差异大时,最少请求/P2C 更稳;若缓存局部性关键,可对特定路由使用一致性哈希,而非把整个站点都粘住。

    2、注意事项

    需要统一真实客户端地址、TLS 策略、超时和重试预算;WAF 规则先观察再阻断;上传、下载和流式接口单独设置大小与超时;健康检查要覆盖核心依赖但不能执行真实写操作。

    (二)数据库、消息队列与自定义 TCP

    1、推荐思路

    优先考虑四层 TCP 负载均衡或协议专用代理。数据库读写分离、主从角色和事务状态不是通用四层算法能理解的,需由数据库代理、驱动或服务发现提供角色感知。仅用轮询把写请求发到多个节点可能直接破坏一致性。

    2、注意事项

    连接池使连接很长,新节点上线后流量迁移慢;健康检查不能只看端口,应验证角色与只读/可写状态;故障切换要考虑事务、会话变量、预处理语句和复制延迟。负载均衡器只能选择连接目标,无法替代数据库一致性协议。

    (三)WebSocket、游戏与实时通信

    1、推荐思路

    四层最少连接适合协议通用和高并发接入;若需要 HTTP 升级鉴权、Cookie 路由或统一 TLS,可使用支持 WebSocket 的七层代理。连接一旦建立天然粘在后端,容量规划重点是并发、每连接内存、心跳和断线重连风暴。

    2、注意事项

    滚动发布时要长时间排空,或由应用支持可恢复会话;后端故障会断开连接,负载均衡无法把现有 TCP 状态迁到另一实例。客户端应指数退避重连,平台设置连接速率保护,避免大量终端同时重连形成第二次冲击。

    (四)缓存与对象分片

    1、推荐思路

    一致性哈希、Rendezvous 或 Maglev 可保持对象到节点的稳定映射,减少扩缩容时缓存重建。若使用多级缓存,可先按地域/可用区选池,再在池内按对象键哈希。

    2、注意事项

    热点键需要复制、请求合并或单独限流;节点权重变化同样会触发映射迁移;缓存穿透和雪崩期间,回源数据库可能先被压垮。哈希稳定性不是完整的缓存韧性方案。

    (五)UDP、QUIC 与 HTTP/3

    1、推荐思路

    普通 UDP 服务可由四层设备按五元组维护短期会话。HTTP/3 使用基于 UDP 的 QUIC,并在传输层集成加密与多路复用;若只做四层转发,入口看不到 HTTP 路径,若需要七层路由就要终止 QUIC/HTTP/3。

    2、注意事项

    QUIC 支持连接迁移,客户端地址变化时 Connection ID 比五元组更稳定;设备是否支持相关路由机制需明确验证。UDP 没有可靠关闭信号,状态超时过长浪费表项,过短会让持续会话重新分配。

    选型从协议和应用语义开始,再结合状态、连接寿命、规模与故障目标,而不是先选产品。

    十二、常见误区与失败模式

    (一)把均匀请求数当成均匀负载

    1、为什么会错

    请求成本、连接寿命、响应大小和实例能力不同,QPS 相同不代表 CPU、内存或队列相同。HTTP/2 连接复用还会让连接数与请求数脱钩。正确做法是同时观察在途工作、资源利用率与尾时延。

    2、怎样修正

    先按请求类型或路由分池,减少池内成本方差;异构实例使用权重;长连接使用最少连接或连接成本;多路复用协议使用活动请求;成熟后再引入延迟或后端负载报告。

    (二)把健康检查写成“永远成功”

    1、为什么会错

    固定返回 200 的 /health 只能证明 Web 进程还能响应,无法证明线程池、数据库、依赖服务和关键配置可用。故障实例继续接流量,用户请求失败,而监控仍显示健康。

    2、怎样修正

    区分存活与就绪;就绪检查验证接流量所需的关键条件;依赖检查设置超时和隔离,避免一个下游抖动让整个上游池同时摘除;把真实请求错误作为被动信号补充主动探针。

    (三)无限重试“提高成功率”

    1、为什么会错

    故障时重试把一次工作变成多次,增加队列与超时,导致更多请求失败并继续重试。非幂等操作还会产生重复副作用。

    2、怎样修正

    限制可重试错误、次数和总时间;使用退避与抖动;设置全局预算;把重试调往不同后端;采用幂等键;当集群容量不足时优先限流和降级,而不是继续制造工作。

    (四)粘性会话被当成高可用

    1、为什么会错

    粘性只是提高回到同一节点的概率,节点故障时本地状态仍然丢失。源 IP 又可能被 NAT 聚合或频繁变化,导致热点和漂移。

    2、怎样修正

    把关键状态放入共享或可复制系统;粘性作为性能优化,不作为唯一正确性条件;验证节点增删和故障时的用户体验;对必须本地化的状态设计复制与恢复协议。

    (五)忽略负载均衡器自身故障

    1、为什么会错

    单实例代理、单区域 VIP、单一控制面或共享证书服务都可能成为新的单点。后端再多,入口不可用时仍然整体中断。

    2、怎样修正

    数据面跨故障域、多活或可快速切换;控制面与数据面解耦;保留最近有效配置;证书和关键规则提前缓存;对入口故障进行与后端故障同等强度的演练。

    十三、进一步思考:负载均衡是一套反馈控制系统

    (一)调度器为什么会振荡

    1、延迟反馈与羊群效应

    多个调度器看到某节点延迟最低,同时把流量转过去;指标经过采样和传输后才反映过载,此时它们又同时离开。系统在节点之间来回摆动。这与控制系统中的反馈延迟和增益过高相似。

    2、稳定性设计

    可采用 EWMA 平滑、随机采样、权重变化限速、最小/最大权重、滞后阈值和探索流量。新策略先在少量流量上验证,不要让算法直接追随瞬时 CPU。优秀算法不仅追求瞬间最优,还要在噪声和延迟存在时保持稳定。

    (二)局部最优可能损害全局

    1、把请求送到最快节点未必最便宜

    跨区域最快节点可能产生高额流量费用或违反数据驻留要求;把所有请求送到缓存命中率最高节点可能使该节点过热;让每个客户端独立选择最少连接节点,可能因为视图不同而形成全局偏斜。

    2、多目标调度需要优先级

    生产调度通常先满足硬约束,再优化软目标。可采用以下顺序:

  • 合规、租户隔离和协议兼容;

  • 健康、熔断容量和故障域;

  • 本地性、成本与版本策略;

  • 延迟、利用率和均匀度;

  • 缓存局部性与实验分组。

  • 把所有目标揉成一个难以解释的分数,会让事故排查困难。分层过滤加简单打分,往往比一个“聪明但不可说明”的模型更可靠。

    (三)未来方向:从代理中心到协同调度

    1、内核与硬件数据面

    eBPF、XDP、SmartNIC 和 DPU 将更多四层转发、观测和安全能力下沉到更靠近包处理的位置,减少上下文切换并提高吞吐。挑战是程序验证、可移植性、调试和控制面一致性。

    2、应用成本感知

    标准化负载报告让后端暴露 CPU、队列或请求成本,客户端和代理据此调整权重。未来调度更可能从“观察结果”走向“服务主动表达承载能力”,但需要防止指标欺骗、过期和跨服务不可比。

    3、AI 可以辅助,但不应绕过安全边界

    机器学习可用于容量预测、异常检测、参数建议和流量模式分类,却不应直接无约束地修改生产路由。任何自动策略都需要目标函数、约束、变更幅度、回滚条件和人工接管。对高可用系统而言,可解释且可回退通常比理论上的极致优化更重要。

    能力演进不是用复杂算法替换简单算法,而是逐步补齐发现、健康、反馈、保护和治理闭环。

    十四、总结:正确的负载均衡是一种系统能力

    (一)四个结论

    1、意义

    负载均衡通过稳定入口把动态实例组织成资源池,使横向扩展、故障隔离、平滑发布和统一治理成为可能。它不能凭空创造容量,但能减少热点、提高有效利用率,并在故障时有序转移工作。

    2、实现

    实现位置包括 DNS/Anycast、四层网络数据面、七层反向代理、客户端库、服务网格和工作队列。生产系统常多层组合;每层应有清晰职责、独立容量和一致的超时/重试预算。

    3、算法

    轮询、加权轮询、随机、最少连接、最少请求、P2C、延迟感知、普通哈希、一致性哈希、Rendezvous、Maglev 和自适应权重各有前提。算法应匹配工作负载,并以真实分布和故障测试验证。

    4、四层与七层

    四层以连接和传输协议为中心,通常更通用、更轻;七层以请求语义为中心,能够精细路由、安全治理和可观测。二者不是互斥等级,而是不同能力边界,常在同一链路协同。

    (二)一份落地检查清单

    1、设计前

    • 已确认协议、连接寿命、请求成本和状态位置;

    • 已定义 SLO、故障发现时间、排空时间和单故障域容量目标;

    • 已明确 TLS 终止点、真实客户端地址和合规约束;

    • 已区分全局、区域、入口与服务间调度职责。

    2、上线前

    • 健康检查覆盖就绪条件并设置迟滞;

    • 负载均衡器与控制面均跨故障域;

    • 算法和权重有压测依据;

    • 超时、重试、熔断、限流和连接池协同;

    • 新实例慢启动,旧实例可排空;

    • 配置可校验、灰度、审计和快速回滚。

    3、运行中

    • 按后端、路由、版本和故障域观察 QPS、在途量、错误和尾时延;

    • 监控连接表、端口、文件描述符、包速、带宽与 TLS 握手;

    • 记录配置版本和路由原因;

    • 定期演练实例、可用区、入口和控制面故障;

    • 用实际结果重新校准权重、阈值和容量预留。

    最后可以用一句话概括:负载均衡不是“把流量平均切开”,而是持续把合适的工作,在合适的时刻,以可控的风险送到合适的处理者。

    可参考的文章与规范

    以下链接以标准组织、开源项目和云平台的官方资料为主,适合继续核对协议定义、产品能力与实现细节:

  • IETF RFC 9293:Transmission Control Protocol (TCP)

  • IETF RFC 9110:HTTP Semantics

  • IETF RFC 8446:The Transport Layer Security (TLS) Protocol Version 1.3

  • IETF RFC 9000:QUIC: A UDP-Based Multiplexed and Secure Transport

  • IETF RFC 9114:HTTP/3

  • NGINX:Using nginx as HTTP load balancer

  • NGINX:HTTP Upstream Module

  • NGINX:Stream Upstream Module

  • HAProxy:Configuration Manual

  • Envoy:Supported Load Balancers

  • Envoy:Health Checking

  • Linux Virtual Server:Job Scheduling Algorithms in LVS

  • Linux Kernel:IPVS Sysctl Documentation

  • Kubernetes:Virtual IPs and Service Proxies

  • Kubernetes:Gateway API

  • AWS:Application Load Balancer

  • AWS:Network Load Balancer

  • AWS:Application Load Balancer Target Health Checks

  • Google Cloud:Choose a Load Balancer

  • Microsoft Azure:Application Delivery and Performance

  • Google Research:Maglev: A Fast and Reliable Software Network Load Balancer

  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » 把流量送到正确的地方:负载均衡的原理、算法与四层/七层工程实践
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!