「后端健康」与「客户端 503 / 卡死 / 偶发 RST」可以同时为真。排障若从 Grafana 面板名或业务口号起步,容易在 LB、TLS、上游之间空转。本系列前 12 篇给出的坐标系,足以把多数故障压进有限几格。
本文是排障篇:给出五轴清单,并说明
Runtime 只读命令、HTTP 日志与 stats
页面各自钉在哪一层。命令只写语义;不粘贴未实跑的
show info / show sess / CSV stats
输出。菜谱脚本见 network/56。
本文是「HAProxy / 数据面代理内核」系列第 13 篇(共 14 篇)。→ 系列目录
篇目 核心内容 第 12 篇 · Seamless reload FD 交接与排空 第 13 篇 · 排障与可观测 五轴 → 信号落点 第 14 篇 · 选型收束 排除树与开放问题
版本锚定:HAProxy 3.4.3 Management Guide Unix Socket commands(
show info/show stat/show sess/show errors/show activity等)。清单是工程方法,不是厂商 runbook 全文。
一、先选轴,再动命令
Accept / bind 轴: 听没听上?FD 交接是否半成功?
Stream / mux 轴: 连接进了哪条 stream?卡在编解码/复用?
ACL / 路由轴: 规则命中了哪个 backend?改写副作用?
Upstream / health 轴:server 状态、队列、检查与熔断感?
Reload / Runtime 轴: 新旧进程并存?热改与文件真相分叉?
flowchart TD
symptom["Symptom: 5xx / stall / RST / sticky miss"] --> axis["Pick one axis"]
axis --> ab["Accept / bind"]
axis --> sm["Stream / mux"]
axis --> ar["ACL / routing"]
axis --> uh["Upstream / health"]
axis --> rr["Reload / Runtime"]
ab --> sig["show info / listeners / logs"]
sm --> sess["show sess / show errors"]
ar --> acl["show acl / map + httplog"]
uh --> st["show stat / show servers / table"]
rr --> proc["Master CLI show proc"]
默认顺序(可裁剪):
- 日志定层(frontend / backend / 终止状态码)。
show stat(或 stats 页面)看 frontend 与 server 计数器是否在动。- 怀疑会话级问题 →
show sess(短格式扫,再按 id 深挖)。 - 窗口内刚 reload → Master CLI
show proc,对 current / leaving 分别核对。 - 仍不一致 → 回对应机制篇(04–12),不要先改业务代码。
Stats socket 与 Master CLI 同属高权限运维面:生产必须
UNIX 权限或网络隔离;level admin
可改流量,只读排障也应审计。
五轴不是五个独立产品,而是同一次请求在不同失败切面上的投影。一次「用户说慢」可能同时触及
mux 缓冲与 upstream
队列——顺序仍是先定主轴,避免并行改超时、权重、ACL 三处。与
Envoy
排障篇 对照:Envoy 把 xDS 一致性单列一轴;HAProxy
对应位置是 Reload /
Runtime(文件世代与内存态)。不要把 Envoy 的
/config_dump 习惯硬套过来——HAProxy
的「世界长什么样」分散在配置文件、show * 与
leaving worker 三处。
二、五轴对照表
| 轴 | 典型症状 | 优先信号 | 机制篇 |
|---|---|---|---|
| Accept / bind | 连接被拒、偶发新建失败、证书绑错端口 | 进程是否在听;reload 竞态;show info
中的监听与 uptime |
03、12 |
| Stream / mux | 卡死、半开、HTTP/2 怪异、超时方向不明 | show sess;show errors;超时配置落点 |
04、05 |
| ACL / 路由 | 打到错误 backend、改写异常、限流误杀 | ACL/map 内容;stick-table;httplog 中的路由结果 | 06、08 |
| Upstream / health | 503、队列堆积、抖动上下线 | server state、check 失败、队列与 maxconn | 07、09 |
| Reload / Runtime | 「改了没生效」、粘滞丢失、双语义 | 文件 vs 内存;peers;leaving worker | 11、12 |
TLS 问题常被误报成「上游挂了」:握手死在 frontend bind / SNI,backend 计数器几乎不动——先用 accept 轴与 第 10 篇 分侧,再进上游轴。
线程与调度异常(单核打满、show activity
倾斜)往往伪装成「上游变慢」。若所有 backend
延迟统计尚可,但 show activity
显示某一线程过载,应回到 第
2 篇 看 nbthread / cpu-map /
是否有粘滞把热点打到单线程,而不是先扩容上游副本。
三、信号落点:stats、日志、sess
3.1 show info /
show stat
| 命令 | 钉什么 |
|---|---|
show info |
进程身份、版本、uptime、全局连接与任务概览(字段随 typed/json 模式变化) |
show stat |
frontend / backend / server 计数器 CSV(或 JSON);吞吐、错误、状态码桶、队列 |
| Stats HTTP 页面 | 同族数据的人读视图;自动化优先 socket |
语义用法:
echo "show info" | socat stdio /run/haproxy/admin.sock
echo "show stat" | socat stdio /run/haproxy/admin.sock解读原则:先看哪一层的计数器在动。Frontend
请求涨而 server 侧不动 → 多半死在 ACL/路由或本层拒绝;server
侧 DOWN / 队列涨 → 上游轴;全局
CurrConns 高但单 server 空闲 → 可能 maxconn /
队列 / 线程不均(第
2 篇)。
把 stats 刮进时序库时,注意基数:按 server 名、响应码、frontend 名打标签很容易爆炸。可观测平台治理见站内可观测性系列;本篇只要求:聚合指标用于选轴,个案用日志与 sess,两套信号不要互相冒充。
3.2 日志
option httplog / tcplog
与自定义 log-format 把终止状态、计时、backend/server
名打到
syslog。排障时日志是「一次请求的判决书」:stats
给聚合,日志给个案。勿用伪造样例代替本环境 format;字段名以
Configuration Manual 的 log-format 表为准。
终止状态码(文档中的会话状态字段)是 HAProxy 方言里最值钱的符号之一:它区分「客户端放弃」「服务器超时」「LB 自身拒绝」等。学会读本环境 format 里的那一列,比再加一块 Grafana 面板更能缩短 MTTR。对照 Nginx access 日志 时,不要假设字段同名同义。
3.3
show sess / show errors /
show activity
| 命令 | 钉什么 |
|---|---|
show sess |
活跃 stream 短列表;show sess <id> /
all 展开 mux/缓冲细节 |
show errors |
近期请求/响应解析错误样本(调试畸形流量) |
show activity |
每线程活动计数;辅助看调度是否单线程打满 |
show sess
成本随并发上升:生产先短格式定位,再对单一 id
深挖。输出字段多、版本敏感——本篇不虚构转储;读文档命令说明,在本机实跑后再入库。
会话级排障的常见顺序:日志里拿到终止状态与大致时间 →
show stat 确认哪一层计数异常 →
若仍有活跃异常会话,再 show sess 对照
frontend/backend 名与超时方向。不要一上来对全量
show sess all:在高并发主机上,那本身就是一次负载事件。
3.4 Stick-table 与 peers
show table / show peers 落在
ACL/限流与跨进程同步轴:表满、过期、peers
断连会导致「限流突然失效」或「粘滞漂移」。与 reload
丢表的交叉见第 12 篇。
把表相关信号并进值班手册时,至少区分三类:键不存在(从未记入或已过期)、键存在但计数不符合预期(规则或采样窗口问题)、peers
显示未连接(同步面问题)。三类对应不同修复,不可都用「清表」应付——盲目
clear table 会瞬间打开放行窗口。
四、按症状走最短路径
4.1 立即 503 / 无上游
排除树:backend 名是否被 ACL 选中 → 是否有
UP server → 是否 maxconn/队列溢出 →
健康检查是否集体判死。工具顺序:日志终止码 →
show stat server 行 →
show servers state(若使用)→ health 轴回 09。
若 frontend 计数不涨,问题可能根本没进 HAProxy(DNS、安全组、上游 LB);五轴从 accept 轴的「听没听上」开始,避免在 server 行上空转。
4.2 「配置已改」但行为旧
分叉:
- 只改了 Runtime → 是否连对进程?reload 是否冲掉内存态?
- 只改了文件未 reload → 结构面未生效。
- 刚 reload → leaving worker 仍服务长连接;Master CLI 分进程核对。
第四种常见分叉:改的是 map/ACL 文件,但进程内仍是旧内存映像——需要 Runtime 更新条目或 reload,取决于你们的更新路径。文件 mtime 新不等于数据面已加载。
4.3 粘滞 / 限流异常
先 show table
看键是否存在、计数是否符合预期;再问 peers 是否同步、reload
是否空表。勿先怀疑 LB 算法「随机」。对照 network/56
的 stick-table 菜谱时,机制失败模式以第 8 篇为准。
4.4 新建连接偶发失败
优先 accept/reload 轴:是否处于 reload 窗口、是否未走
-x/sockpair、内核是否具备
SO_REUSEPORT。对照 Management Guide
对竞态窗口的说明,而不是先调业务超时。与 第 12
篇、Envoy
hot-restart
一样:进程交接窗口的失败应记在运维变更上,而不是记在「随机网络抖动」上。
4.5 证书 / TLS 相关
症状:握手失败、偶发告警、HTTP 正常但 HTTPS
不行。路径:确认 bind 与 SNI 选证(accept 轴)→
客户端协议/ALPN → 再问后端是否也做 TLS。Runtime
换证事务若中途 abort,可能留下「以为更新了」的错觉——用只读
SSL 相关 show 命令核对(命令名以 3.4.3
表为准),不要只看磁盘文件 mtime。
五、扩展边界:SPOE 与 Lua(一行)
SPOE(Stream Processing Offload Engine)与 Lua 把逻辑推出或嵌入数据面:排障时多一跳失败域(agent 超时、Lua 错误)。本系列不展开 SDK;若路径上挂了 filter/SPOE,五轴之外先确认扩展是否返回错误或阻断——然后再回 mux/ACL 轴。选型层对扩展税的讨论见 第 14 篇;产品对照见 network/60。
与 Envoy Wasm/外置 auth 对照(Envoy 选型):扩展永远是「能力换排障半径」。HAProxy 的默认力量在内建 ACL/stick-table;把核心限流外包给 SPOE 前,先确认五轴清单里有没有给 agent 留观测位。
值班交接可用一页纸固化:症状 → 主轴 → 三条只读命令 →
禁止事项(例如高峰全量 show sess all、未确认
peers
前清整表)。机制篇负责「为什么」;这一页负责「半夜先干什么」。把页面挂进
runbook 后,再链回本系列对应章节,避免 runbook
与机制文各说各话。
把五轴写进事故复盘模板时,强制填写「主轴 / 排除过的轴 / 用过的只读命令 / 是否动过 Runtime」。许多复盘只写「重启恢复」,丢失了本可沉淀的机制结论。若恢复手段是 reload,必须记录是否配置了 peers、是否丢失 stick-table、leaving 是否被 hard-stop——否则下次同一症状仍会从头猜。
与可观测平台对接时,优先导出稳定、低基数的计数器(frontend 请求量、5xx、server UP/DOWN、队列深度),把高基数键(客户端 IP、完整 URI)留在采样日志。平台侧告警应指向轴,而不是指向「HAProxy 红色」——红色没有机制含义。
开放问题接到选型篇:大规模下 show sess
与全量日志是否反而淹没信号?Runtime 与 reload
混用时,排障证据链如何机器化?这些问题不在本篇关闭,但五轴提供了讨论时必须使用的名词。没有名词,值班只会留下「重启好了」三个字。
对多租户或共享入口的部署,还要在五轴之外标注「租户或监听器隔离是否失效」:一个 frontend 的 ACL 误改可能把流量打进别人的 backend。此时日志里的 frontend/backend 名字比全局 QPS 更重要。共享进程的爆炸半径是选型税的一部分,排障时先问「是否误伤邻居」,再问「上游是不是真挂了」。
命令输出入库前必须标注版本、主机与是否删减;本系列坚持不贴伪造转储,是为了避免读者把示例字段当成
3.4.3 的保证布局。字段以你本机 show info typed
/ 文档表为准。
五轴用熟之后,多数故障会变成「选错轴」而不是「不会敲命令」。把时间花在定轴上,比花在多开几个监控面板上更接近机制排障。
六、参考资料
规范 / 官方文档(A)
- HAProxy 3.4.3 Management
Guide:
show info、show stat、show sess、show errors、show activity、show table、show peers、Master CLIshow proc。 - HAProxy 3.4.x Configuration
Manual:log-format、
stats、超时与错误页。
工程对照(B / 站内)
- network/56:Runtime 与运维脚本。
- Envoy 生产排障:另一套五轴对照(路径 / xDS / 上游)。
- network/60:网关可观测方言差异。
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【HAProxy 数据面】ACL / 规则引擎:求值顺序、副作用与 stick-table 耦合
把 ACL 与 http-request / use_backend 当作数据面机制:说明连接期到 L7 的求值顺序、动作副作用如何改写后续条件,以及与 stick-table 限流/标记的耦合点;不写 ACL 关键字百科。
【HAProxy 数据面】Health-check 引擎:探活调度、httpchk/tcp-check 与 agent-check 边界
区分健康检查引擎与数据面请求调度:说明默认 TCP 探活、httpchk/tcp-check 规则集、agent-check 的独立控制面语义,以及与 soft-stop/排空的交互提示;不写伪造检查日志。
【HAProxy 数据面】Backend / server / LB:算法、队列与连接复用边界
把 balance 算法、server maxconn/队列与 http-reuse 当作数据面机制:说明无持久化信息时如何选主、队列满与无 server 时如何失败,并轻对照 Envoy cluster/连接池边界。
【HAProxy 数据面】Stick-table:键类型、容量、跨线程可见性与 peers/reload
说明 stick-table 的键类型、size/expire/store、nbthread 共享内存与 nbproc 不共享的边界,以及 peers 复制与 reload 继承;覆盖表满等容量失败模式。