3. 四层与七层负载均衡的工程边界
四层负载均衡(L4)工作在传输层,它看到的对象是 IP 地址、端口和 TCP/UDP 报文段;七层负载均衡(L7)工作在应用层,它看到的是 HTTP 请求行、头部字段、gRPC 方法名或 WebSocket 握手报文。这个差异不是"层次高低"的抽象说法,而是直接决定了转发路径、连接模型、可观测粒度和故障边界。理解工程边界,核心是回答三个问题:连接在谁手里终结、协议在谁手里解析、内容在谁手里决策。
连接模型:转发与代理的本质区别
L4 的典型实现是 DNAT 加连接跟踪。客户端与虚拟 IP(VIP)建立 TCP 三次握手,内核的 conntrack 表记录五元组,后续报文按哈希结果改写目的地址转发到某台后端,后端看到的源地址可能是客户端真实 IP(DSR 模式)或负载均衡器地址(NAT 模式)。整条 TCP 连接在客户端与后端之间端到端存在,负载均衡器只做报文级搬运,不参与序列号确认,也不缓存应用数据。
L7 则是"两段连接":客户端先与负载均衡器完成 TCP 握手,负载均衡器再作为客户端向后端发起一条新连接。请求被完整读取、解析、按规则选择后端、重新封装后转发。这意味着 L7 天然具备连接复用能力——多个客户端请求可以复用同一条到后端的连接,也意味着它必须承担解析开销和内存缓冲。
连接保持的代价由此分化。L4 的会话保持通常基于源 IP 哈希或一致性哈希,粒度粗、无状态、开销极低,但 NAT 环境下大量客户端共享出口 IP 时容易倾斜。L7 可以基于 Cookie 插入、HTTP 头部或 gRPC 元数据做精细保持,代价是需要在内存中维护会话映射表,且负载均衡器重启后映射可能丢失,需要配合后端自身的会话存储。
协议解析与内容路由的代价
L7 的解析代价体现在三个层面。第一是 CPU:每个请求都要做 HTTP 头部解析、TLS 解密(若终结 TLS)、规则匹配。以 Nginx 为例,单核处理 HTTPS 短请求通常在数千到一万 QPS 量级,而 L4 转发可达数十万 PPS。第二是内存:请求体需要缓冲,大文件上传或流式响应会占用大量内存,必须设置 client_max_body_size 和 proxy_buffering 等参数控制。第三是延迟:多一次解析和重新封装,通常增加 0.1~1ms,对延迟敏感的场景需要评估。
内容路由的代价还体现在规则复杂度上。基于 URL 前缀的路由是 O(1) 前缀树匹配,开销小;基于正则表达式的路由需要逐条匹配,规则数量多时线性增长;基于 gRPC 方法名的路由需要解析 HTTP/2 帧,开销更高。工程上应控制单实例路由规则数量,优先使用前缀匹配,正则规则放在最后兜底。
典型场景选型
| 场景 | 推荐层级 | 关键理由 | 注意事项 |
|---|---|---|---|
| TCP 长连接(数据库代理、消息队列) | L4 | 连接生命周期长,L7 代理会引入额外内存和超时管理 | 需配置空闲超时与连接数上限 |
| HTTP 短请求(REST API) | L7 | 需要按路径路由、灰度、限流、可观测 | 注意 keepalive 复用与后端连接池 |
| gRPC | L7(HTTP/2) | 需解析 service/method,支持多路复用与流控 | L4 只能按连接哈希,无法按方法路由 |
| WebSocket | L7 握手 + L4 转发 | 握手阶段需解析 Upgrade 头,升级后转为长连接 | 需配置 upgrade 头透传与长超时 |
WebSocket 是典型的混合场景:握手阶段是 HTTP 请求,需要 L7 解析 Upgrade: websocket 头并选择后端;升级完成后连接变为全双工长连接,L7 代理需要保持连接并转发帧,此时开销接近 L4 但多了帧解析。工程上常见做法是 L7 完成握手后,将连接标记为长连接并调整超时策略,避免被空闲超时误断。
混合部署策略
生产环境很少只用一层。典型架构是"L4 入口 + L7 业务网关":最外层用 L4(如 LVS、DPDK 转发)承接海量连接和 DDoS 清洗,将流量按 VIP 或端口分发给不同的 L7 集群;L7 集群(如 Nginx、Envoy)负责 TLS 终结、内容路由、限流和可观测。这样 L4 承担高吞吐转发,L7 承担精细控制,各司其职。
另一种是"L7 内部再分流":同一 L7 集群内,短请求走普通 upstream,长连接走独立 upstream 并配置不同的超时和连接池参数。例如 Nginx 中为 WebSocket 单独定义 upstream 并设置 proxy_read_timeout 3600s,为 REST API 设置 proxy_read_timeout 30s,避免长连接占用短请求的连接池资源。
proxy_buffering off 并设置合理的 proxy_read_timeout,同时监控代理层的内存与连接数指标。
最后需要明确故障边界:L4 故障通常表现为连接建立失败或转发中断,排查聚焦于 conntrack 表、网卡队列和健康检查;L7 故障则可能表现为 502/504、请求排队、内存溢出或规则误匹配,排查需要结合访问日志、upstream 响应时间和规则命中统计。理解这条边界,才能在选型和排障时快速定位问题所在的层次。