土法炼钢 · 系统与基础设施

【HAProxy 数据面】选型收束:机制排除树与系列开放问题

文章导航

分类入口
networkproxy
标签入口
#haproxy#nginx#envoy#ebpf#selection#stick-table#quic#runtime-api#3.4.3

目录

前 13 篇把 HAProxy 钉成可排障的数据面内核:线程与 accept、stream/mux/HTX、ACL、上游与 stick-table、健康检查、TLS、Runtime 与 seamless reload。选型若再写成「各有优劣看场景」,等于把机制丢掉。

本文是终章:用机制排除树收束相对 Nginx / Envoy / eBPF 的位置,回收阅读路径,并列出仍开放的问题。不做跨产品延迟排行榜;产品叙事外链站内已有篇章。

本文是「HAProxy / 数据面代理内核」系列第 14 篇(共 14 篇 · 终章)。→ 系列目录

篇目 核心内容
第 13 篇 · 排障与可观测 五轴故障清单
第 14 篇 · 选型收束 排除树、阅读回收、开放问题

版本锚定:机制结论对齐 HAProxy 3.4.3。与 网关选型(network/60)Envoy 选型收束Nginx 深度HAProxy 工程(network/56) 分工:那些文负责产品表与配置菜谱;本文负责「内核能力是否必要」。


一、先排除,再选择

flowchart TD
  need{"Need rich L4/L7 LB<br/>+ Runtime ops without xDS?"}
  need -->|"no, static reverse proxy"| ngx["Nginx file + reload"]
  need -->|"yes"| api{"Need ACK-able API<br/>config tree + filters?"}
  api -->|"yes"| env["Envoy / mesh dataplane"]
  api -->|"no"| l7{"Need full HTTP policy<br/>stick-table / ACL depth?"}
  l7 -->|"no, L3/L4 only"| ebpf["eBPF / IPVS path"]
  l7 -->|"yes"| hap["HAProxy data plane"]
问题 若答案为「否」 倾向
要以代理/LB为主业,而不是 Web 静态站 + 反代? 静态站权重高 Nginx(55
配置必须 API 热更新且可 ACK、Filter 链组合? 文件 + Runtime/reload 可接受 留在 HAProxy / Nginx 格
要深度 ACL + stick-table + Runtime 摘流 仅简单 upstream Nginx 或 L4
只要 L3/L4 转发与身份? 不需要完整 HTTP 应用语义 eBPF / IPVS 等
要每服务独立身份与网格策略? 边缘/节点 LB 足够 再评估 sidecar Envoy(Envoy 16

HAProxy 不是默认赢家:它赢在「经典 L4/L7 LB 内核 + 可热改运行态 + 强 ACL/粘滞」成为一等公民的时候;它输在组织已经押注 xDS 控制面经济学、或内核 L4 已够用的时候。

排除树要诚实对待编制:没有人维护配置真相与 Runtime 纪律时,强行上「复杂 stick-table + 频繁 reload」只会把故障藏进双进程窗口。

也要诚实对待「已经会用 Nginx」的沉没成本:若团队的故障手册、看板与证书流水线全挂在 Nginx 上,仅仅因为「HAProxy Runtime 更强」就迁移,往往低估排障方言切换成本。机制优势要能支付迁移税;否则先在 Nginx 格把 reload 纪律做干净,再评估是否值得换内核。反向亦然——已在 HAProxy 上跑深 ACL/stick-table 的团队,不必为「云原生」三字强行改 Envoy,除非 ACK 树与 Filter 组合已成为硬约束。


二、机制差:Nginx / HAProxy / Envoy / eBPF

维度 Nginx HAProxy(本系列) Envoy eBPF L3/L4
配置一等公民 文件 + reload 文件 + Runtime + reload xDS 资源树 + warming 内核映射 / CNI 策略
请求内核 多进程 worker、阶段式处理 多线程、stream/mux/HTX Main+Worker、Filter 链 内核转发,少 HTTP 语义
动态运维 较窄 权重/state/表/map 热改 CDS/EDS/RDS… 视实现热更新 map
进程交接 worker reload -x / sockpair seamless hot-restart drain 通常无用户态双进程交接
观测方言 access/error + stub stats / sess / table admin 统一树 内核/cilium 可观测

站内 network/60 已有协议与生态横向表。本系列补充的判决句:

混合并不犯规:边缘 HAProxy 做 L7 入口,东西向 L4 交给 eBPF,少数服务再挂 Envoy sidecar。代价是多套排障坐标——第 13 篇清单要标明流量先进了哪一层。

进程交接对照一句就够:第 12 篇 的 seamless reload 与 Envoy hot-restart 同属「新听旧排」;差别在日常变更是否经常逼近进程级。HAProxy 用 Runtime 把大量变更留在单进程内;Envoy 用 xDS 做同类事。谁更「现代」不是判据;谁的失败模式你们排得动,才是。

再补一条组织层排除:若变更审批只认「改 conf 并 diff」,Runtime 热改会成为影子通道——要么把 Runtime 纳入同一审批与审计,要么禁止生产手工 socket。机制允许的事,流程可以收紧;反过来用流程假装有 ACK 树,填不满 xDS 那一格。


三、系列阅读路径回收

路径 篇目 收回什么
必读核心 01 → 02 → 04 → 08 → 12 → 13 坐标系 + stream + stick + reload + 排障
请求深挖 03 → 04 → 05 → 06 → 07 accept 到上游
动态运维 11 → 12 → 13 Runtime / reload 联调
对照选型 01 → 13 → 14 五轴 + 排除树
配置预习 network/56 单篇菜谱;机制仍回本系列

五个关键问题(系列 index)到终章仍然够用:争议要么落在「要不要 API 驱动路径」,要么落在「粘滞/限流状态如何跨 reload 存活」,很少落在营销形容词上。

写给后续维护者:升 3.4.x patch 或改 master-worker/Reload 单元时,先重跑第 13 篇与 accept/reload 相关的门禁,再更新本篇排除树的假设。

若读者时间只够一篇:读 01 全景 建立缺口意识,再读本篇排除树,最后按自己的主轴跳进 08/11/12/13 之一。完整通读的收益是「症状能落格」;跳读的风险是把 Runtime 当成万能控制面,或把 seamless 当成零失败保证。

与站内相邻系列的接法:先修配置直觉读 56;要对照 worker 模型读 55;要对照 API 驱动读 Envoy 目录16;产品勾选读 60。本系列不替代其中任何一篇,只补「一次连接与一次 reload 在内核里发生了什么」。


四、系列级开放问题

下列问题有工程与社区争议;本系列给了机制语言,但不假装已关闭。用延迟排行榜代替回答。

4.1 Stick-table 规模与 peers 一致性

表容量、过期、跨线程更新与 peers 分片在极大键空间下,延迟与一致性如何权衡?单机 peers「抗 reload 丢表」与多机同步的失败模式是否共用同一套可观测信号?(入口:第 8、12、13 篇;Configuration Manual peers / stick-table。)

可检验子问题:在给定 sizeexpire 下,满表驱逐与 peers 断连,能否被 show table / show peers 与日志充分区分,还是必须外挂指标?

进一步:当表用于安全封禁时,短暂的 peers 分区是否可能造成「一侧重放、一侧仍封」的策略分裂?这类分裂在文件驱动模型里没有 xDS 式的版本向量,只能靠运维约定与告警——这是机制间隙,不是配置笔误。

4.2 QUIC / HTTP/3 在 3.4 线上的成熟度边界

QUIC frontend 与 TCP/HTTP/1·2 路径在 mux、超时、连接迁移、排障信号上何处分叉?Runtime / reload 对 QUIC listener 的约束(文档已提示部分动态删除限制)如何写入发布门禁?(入口:第 4–5、10 篇;3.4 Configuration Manual / Management Guide 中 QUIC 相关命令说明。)

可检验子问题:同一套 ACL/backend 配置下,H3 特有失败能否被现有 httplog 终止码与 show sess 表达,还是必须协议专用计数器?

Envoy 16 列出的 HTTP/3 开放问题平行:两端都在追协议成熟度,谁「领先」随版本漂移;选型应比较你们要上的那条协议路径是否已有排障坐标,而不是比较营销页的 H3 勾选框。

4.3 Reload vs Runtime 运维模型的可观测性

结构走文件、运行态走 Runtime 时,「配置已生效」的 SLO 应钉在哪:磁盘 mtime、reload 完成、还是某条 show * 断言?混用导致的真相分叉,如何在不引入完整 xDS ACK 树的前提下可审计?(入口:第 11–13 篇;对照 Envoy warming/ACK。)

可检验子问题:一次变更流水线能否输出机器可读的证据包(文件哈希 + reload 世代 + 抽样 show stat 字段),使「Git 与内存一致」成为门禁而非口头约定?

子问题的反面:若证据包成本高于变更收益,组织是否应收敛变更面——少用动态 server、少用长期只活在内存的 map——而不是假装有 ACK。可观测性解决不了「故意让真相分叉」的流程问题。

network/60 的产品表合读时:表回答「生态与协议勾选」;本开放问题回答「勾选之后夜里能不能定位」。两者缺一,选型讨论会在会议里循环。

这些问题不要求终章拍板。它们要求后续文章或事故复盘带着五轴与排除树回去量:量的是表满驱逐率、peers 断连、reload 窗口失败、Runtime/文件漂移——而不是再写一张无口径的代理延迟榜。

终章立场可以收成一句:HAProxy 数据面值得写成系列,是因为它把经典 LB 的路径、热改与 seamless reload 变成可命名机制;选型与开放问题若离开这些名字,讨论会退回品牌口号。


回到系列开头的缺口陈述:站内已有配置菜谱与网关产品表,缺的是「路径与动态运维的可核对内核」。若读完 14 篇仍只能复述功能清单,说明阅读停在目录;若能在故障里说出「这是 stick-table 在 reload 未配 peers 时的预期清空」或「这是 Runtime 与文件分叉」,机制文才算交货。

最后提醒一次边界:本系列不写 Enterprise 专有能力、不写 Lua/SPOE SDK、不做跨代理延迟榜。开放问题欢迎用事故数据与官方文档补完,不欢迎用无口径截图开战。版本钉在 3.4.3;升版时先重跑 Management Guide 中与 -x、Master CLI、QUIC 相关的章节差分。

若只用一句话向架构评审交代本系列:HAProxy 占据「文件为结构真相、Runtime 为运行态、seamless reload 为结构世代切换」这一格;Nginx 更偏 Web+反代与更窄动态面;Envoy 占据 ACK 式资源树与 Filter 组合;eBPF 占据 L3/L4 内核路径。选格先于选品牌,排障坐标先于延迟传说。

对平台团队的务实建议:先用第 13 篇清单跑通一次真实故障或演练,再决定要不要为了「动态配置」迁到 Envoy。若演练里卡在 stick-table 与 reload,优先补 peers 与变更门禁;若卡在「没有可编程 Filter」,再评估 Envoy。机制排除树的正确用法是缩短错误迁移,而不是证明某品牌永远正确。

至此,系列在机制层闭合:从 frontend 到 seamless reload,再到排障与选型。后续补丁级更新应改版本钉与开放问题进展,而不是重写排除树的问题顺序。

五、参考资料

规范 / 官方文档(A)

站内对照

研究 / 争论入口(方向,非排名)

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。


By .