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

【HAProxy 数据面】数据面全景:从 Frontend 到 Seamless Reload 的代理内核

文章导航

分类入口
networkproxy
标签入口
#haproxy#data-plane#load-balancer#frontend#stick-table#htx#seamless-reload#3.4

目录

站内 HAProxy 工程 已经把 frontend/backend、ACL 菜谱与 Runtime 运维直觉铺成一张地图;Nginx 深度Envoy 数据面 各占「多进程文件驱动」与「API 驱动 Filter/xDS」一格。网关选型 把三者放进产品对比。读者仍缺一角:一次连接如何经 bind/accept → stream/mux → HTX/ACL → backend,以及 Runtime 热改与 seamless reload 各自保证什么、丢什么。

本文是「HAProxy / 数据面代理内核」系列第 1 篇,只做三件事:

  1. 画出 HAProxy 相对配置运维单篇、Nginx、Envoy 的生态位与缺口。
  2. 钉住后续章节共用的五条坐标系,并交代用户态事件驱动 LB 的设计谱系与开放争论。
  3. 给出与站内系列的分工,以及 14 篇阅读路线。

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

篇目 核心内容
第 1 篇 · 数据面全景 生态位、主线坐标系、系列路线
第 2 篇 · 线程与调度 nbthread / thread-group、共享内存边界
第 3–5 篇 · 接入路径 accept → stream/mux → HTX
第 11–12 篇 · 动态性 Runtime API 与 seamless reload

版本锚定:HAProxy 3.4.3(LTS 线 3.4;2026-07-29)。官方 Starter Guide / Management Guide / Configuration Manual(docs.haproxy.org/3.4/)与源码树 haproxy/haproxy tag v3.4.3。本篇以定位与路线为主,不粘贴未执行的 show info / show sess / stats 输出,也不编造 QPS。


一、生态位:本系列补哪一角

Nginx / HAProxy / Envoy 常被塞进同一张「反向代理」表,但默认把什么当一等公民不同——格子不是互斥,而是故障归因时先看哪一层

flowchart TB
  subgraph proxies ["Proxy paradigms"]
    NGX["Nginx<br/>multi-process file-driven"]
    HAP["HAProxy<br/>file/Runtime L4/L7 LB kernel"]
    ENV["Envoy<br/>API-driven filter dataplane"]
    EBPF["eBPF L3/L4<br/>kernel datapath"]
  end
  subgraph ops ["Ops / product layers"]
    CFG56["network/56<br/>HAProxy config map"]
    SEL60["network/60<br/>gateway selection"]
  end
  CFG56 -.->|"need path + failure modes"| HAP
  NGX -.->|"contrast worker model"| HAP
  HAP -.->|"contrast control plane"| ENV
  EBPF -.->|"L7 still needs userspace"| HAP
  HAP --> SEL60
  ENV --> SEL60
形态 一等公民 典型代价中心 站内入口
Nginx 多进程 配置文件 + worker 隔离 reload 窗口、共享状态缺失 network/55
HAProxy 数据面 frontend/backend + Runtime + stick-table 线程共享、mux/HTX、reload FD 交接 本系列
Envoy 数据面 xDS 资源 + Filter 链 匹配、编解码、warming、上游池 envoy/
配置运维单篇 会配、会查 stats 不回答「卡在哪一层」 network/56
eBPF L3/L4 内核策略 / 负载均衡 不解析完整 HTTP 语义 linux-net / Cilium

一句话:本系列占住「文件配置 + Runtime 热改驱动的经典 L4/L7 LB 内核」那一格——不替代 56 的菜谱,也不重写 Envoy 的 Filter/xDS 全书。

主线引擎取 HAProxy 3.4.3:文档树与源码 tag 对齐,适合做「从 accept 到 reload」的连续拆解。HAProxy Enterprise 专有能力、Lua/SPOE SDK 教程不进正文;仅在选型边界出现。

读者若只带走一句:会配 frontend/backend 只是地图入门;能指出失败落在五条轴的哪一条,才算进入本系列的能力模型。


二、缺口:相对 56 / 55 / Envoy 还缺什么

已有内容 视角 本系列补什么
network/56 配置模型、ACL 菜谱、Runtime 用法、运维调优 源码级路径、失败模式、与 reload 的语义边界
network/55 Nginx 事件模型 / worker / upstream 对照句;不重写 Nginx
envoy/ API 驱动 Filter + xDS 对照「文件/Runtime 驱动」那一格
network/60 网关选型排除树 机制前提;不重做产品评选表

结论:读者会写 frontend/backend、会用 Runtime socket,但不知道 accept 之后 stream/mux 如何分层、HTX 改写落在哪、stick-table 在多进程下不共享意味着什么、Runtime 改权重与 seamless reload 各自保证什么。

Envoy 第 1 篇 对称:那边钉的是「控制面已推送为何仍黑洞」;这边钉的是「配置已 reload / 权重已 set 为何仍丢状态或卡在错误层」。


三、设计谱系:用户态事件驱动 LB 从哪分叉

3.1 工作定义

本系列默认的 HAProxy 数据面

3.2 学术与工程谱系(本系列回指)

  1. C10K 与用户态事件驱动:把「每连接一线程」换成 poller + 非阻塞 I/O(经典叙述见 Dan Kegel, The C10K problem)。HAProxy Starter Guide / Management Guide 把自己钉成 multi-threaded, event-driven, non-blocking:用事件多路复用调度活动,而不是把调度外包给内核线程切换。
  2. 专用负载均衡器 vs 通用 Web 服务器:Nginx 从静态内容与反向代理共生;HAProxy 从第一天就以代理/LB 为中心(对照 network/56 的定位段)。工程分叉点是:会话粘性、细粒度健康检查、Runtime 改权重是否一等公民。
  3. 单进程多线程演进:早期多进程(nbproc)用进程边界换隔离;现代默认路径是 nbthread + 共享地址空间内的 stick-table/stats,再用 thread-group 约束 NUMA/缓存局部性(3.2 起拓扑感知,3.4 进一步收紧默认每组线程上限等——见 3.4 发布说明)。这与 Envoy Main/Worker「连接钉死 Worker + TLS 快照」同属 shared-nothing 数据面家族,但配置分发协议不同:文件/Runtime vs xDS。

谱系收束句:产品层争论「选哪个代理」;内核层争论「共享状态放在进程内还是进程外、热更新用 Runtime 还是 reload」。 后者才是本系列主战场。

3.3 开放争论(先立靶,后各章拆)

争论 A 侧 B 侧 本系列落点
文件/Runtime vs xDS 可 diff 进 Git、运维面窄 统一控制面、声明式热更新 第 11–12、14 篇;对照 Envoy 9–12
nbproc 多进程 vs nbthread 故障隔离、CPU 重任务拆分 stick-table 进程内共享、检查不翻倍 第 2、8 篇;Management Guide 限制表
「一切经 HTTP/HTX」vs 纯 TCP 统一改写与观测 L4 路径更短、少解析税 第 4–5 篇
Seamless reload vs 永不 reload 配置面完整切换 窗口内 SYN/ACK 竞态与状态复制成本 第 12 篇
Stick-table 规模上限 进程内低延迟粘性 容量、锁、peers 一致性 第 8、14 篇

四、五条坐标系(后续章节回指)

后面每一篇都会落到下面某一条轴上。第 1 篇只钉名字,不展开源码。

4.1 请求路径轴

bind/accept → session → mux → stream
            → (HTTP) HTX + ACL/rules → backend/server → response path

延迟与 5xx / 断开的归因必须先回答:卡在 accept、协议 mux、规则引擎、上游连接,还是健康检查把池掏空? → 第 3–7、9、13 篇。

4.2 线程与共享状态轴

默认一进程多线程,每线程跑同一套事件循环;连接由单线程服务。Stick-table、部分 stats 等在进程地址空间内共享,靠锁与局部性设计控制争用;nbproc 进程不共享 stick-table(Management Guide 明文)。→ 第 2、8 篇。

4.3 协议表示轴

TCP 可用 pass-through mux 少碰语义;HTTP 经 mux 进入 HTX。改写/重定向落在 HTX 上,避免「H2 先转成 H1 字节再解析」的双遍税(内部 doc/internals/api/htx-api.txt 叙事)。→ 第 4–5 篇。

4.4 动态运维轴

Runtime API 可热改权重、上下线、部分表项等;完整 listener/规则拓扑变更往往仍要新进程 + reload。-x / expose-fd listeners / master-worker 决定 FD 如何交接。→ 第 11–12 篇。

4.5 失败归因与可观测轴

Stats、会话转储、日志终止码、stick-table 计数,必须映射回上面四条轴,而不是「先怀疑网卡」。→ 第 13 篇;选型收束在第 14 篇。


五、与站内系列的分工

站内内容 负责 本系列不重复
network/56 单篇配置与运维地图 本系列下沉路径与失败模式
network/55 Nginx worker / reload 仅对照句
envoy/ Filter + xDS 内核 不重写;对称对照
istio-xds/ 网格控制面 不写;选型边界外链
network/60 多代理选型表 机制前提,不重做对比全书
libevent Reactor 通识 HAProxy 调度器 / poller 特有部分

读法:只要「建立 HAProxy 配置坐标系」→ 56 足够;要「一次请求卡在哪、reload 丢了什么」→ 本系列 01 → 04 → 08 → 12 → 13。

若目标是与 Envoy 对照做数据面选型,建议最小交叉阅读:本系列 01+02+12,加上 Envoy 01+02+12——两边各自回答「动态性如何进入热路径」,而不是先比谁的 QPS 宣传更高。


六、14 篇地图与阅读建议

部分 一句话
进程与请求路径 01–06 从全景到 ACL 求值
上游、状态与动态性 07–11 LB、stick-table、检查、TLS、Runtime
生命周期与收束 12–14 reload、排障、选型

最小路径:01 → 02 → 04 → 08 → 12 → 13。
请求路径深挖:再补 03 → 05 → 06 → 07。
动态运维联调:11 → 12 → 13。
做网关选型:01 → 13 → 14,并外链 55 / 56 / 60 / Envoy 16。

本篇不写性能排行。任何「比 Nginx/Envoy 更快」的句子若无本机口径与引用出处,一律视为无效——第 14 篇只给排除树,不给未实测延迟榜。


七、一条请求的「分层检查表」(给后续篇用)

后面排障篇会把字段映射到轴上;第 1 篇先固定提问顺序,避免一上来就改 timeout server

  1. 听得见吗? bind 是否在正确地址/端口;reload 窗口是否丢 SYN;maxconn 是否打满入口。→ 第 3、12 篇。
  2. 协议对得上吗? mode tcp/http、bind 上 TLS、ALPN/H2 是否与客户端一致;mux 是否选错世界。→ 第 3–5、10 篇。
  3. 规则把请求送去哪? ACL / use_backend / redirect 是否短路;stick 是否绑到已下线 server。→ 第 6、8 篇。
  4. 上游还能接吗? 队列、maxconn、健康检查、timeout connect。→ 第 7、9 篇。
  5. 动态面刚改过什么? Runtime 改权重是否可见;是否刚做 seamless reload 导致表/FD 语义变化。→ 第 11–12 篇。

这张表不是产品对比,而是把「代理」拆成可证伪命题。Envoy 系列用 warming/ACK 回答「配置已下发」;本系列用路径轴 + 动态运维轴回答「配置已生效 / 连接已接住」。

工程间隙也先立在这里:官方 Management Guide 对 reload 失败率给过与负载相关的定性量级叙述,那是文档实验语境,不是你机房的 SLO。引用时必须写清来源与条件;本系列正文不把它改写成「生产保证」。


八、参考资料(本篇)

规范 / 官方文档(A)

源码(A)

谱系 / 对照(B 或经典)

站内对照

实验台账


九、小结

  1. HAProxy 的生态位是文件/Runtime 驱动的经典 L4/L7 LB 内核,不是「又一个会 proxy_pass 的 Web 服务器」,也不是 xDS 数据面。
  2. 五条坐标系(请求路径、线程共享、协议表示、动态运维、失败归因)是后续排障的共用语言。
  3. 与 56 的分工:单篇建立配置地图;本系列回答路径与「热改/reload 各自丢什么」。
  4. 开放争论先立靶:共享状态边界、HTTP 统一表示成本、reload 窗口——各章用机制拆,不提前做产品排名。
  5. 分层检查表要求先固定接入与协议,再查规则与上游,最后才怀疑动态运维面。

系列目录 · 下一篇:线程与调度

读完这篇,下一步读什么

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


By .