Stick-table
记住客户端;health-check 塑造「哪些 server
还在可调度集合里」。现场常把「check 失败」与「数据面
503」绑成一件事,却分不清:是探活把机器踢出了农场,还是农场仍在、请求卡在
maxconn
队列。本文钉检查引擎相对数据面的位置与边界。
本文是「HAProxy / 数据面代理内核」系列第 9 篇(共 14 篇)。→ 系列目录
篇目 核心内容 第 8 篇 · Stick-table 跨请求状态 第 9 篇 · Health-check 探活与可调度集合 第 10 篇 · SSL/TLS 终结与透传 上一篇:Stick-table · 下一篇:SSL/TLS 路径
版本锚定:HAProxy 3.4.3 Configuration Manual
option httpchk、http-check、option tcp-check/tcp-check、agent-check;Starter Guide 中与健康检查 / 优雅下线相关的能力叙述。源码 tag v3.4.3。不粘贴伪造 check 日志。
本篇不展开:每一种 http-check expect
匹配器百科、外部监控系统(Prometheus/黑盒)替代方案、DNS
解析器细节。LB 如何消费健康集合见 第 7 篇。
一、两条调度:检查引擎 vs 数据面
数据面路径:accept → 规则 → 选 backend →
在当前可用 server 上 balance →
连接/复用 → 上下游 I/O。
检查路径:按 server 的 check / 间隔 /
端口,由调度器周期性发起独立探测会话(TCP
连接,或再加协议交换),根据结果更新该 server
的运行状态(UP/DOWN 等),从而改变数据面可见的候选集。
维护者对多线程模型的描述:全局实体(listeners、peers、checks、DNS resolvers 等)无会话亲和,各线程都可能处理它们,但同一时刻仍串行于该实体。含义是:
- 探活不是「跟着某个客户端请求走」的旁路 filter;
- 探活消耗的是进程内任务与 FD/连接资源,与业务连接争用调度器,但不共享那条业务 stream 的缓冲语义;
- 数据面线程在选主时读到的是检查子系统写下的状态,而不是当场替客户端再探一次。
flowchart TD
chk_sched["check scheduler"] --> probe["probe TCP/HTTP/agent"]
probe --> state["server operating state"]
state --> lb["LB candidate set"]
client["client request"] --> lb
lb --> data["dataplane connect/reuse"]
因此排障第一问应是:503
时候选集是否已空? 若 server 在 stats 上仍
UP,应转向第 7
篇的队列/maxconn/复用问题,而不是加长
check inter。
二、默认探活与
httpchk
手册对
option httpchk:默认健康检查只尝试建立
TCP 连接;启用 option httpchk 后,在
TCP 建立成功后再发完整 HTTP 请求,2xx/3xx
视为成功,其它响应或无响应视为失败。
可带 method / URI / version / Host 等参数;也可用
http-check 指令集做多步定制(connect / send /
expect / send-state 等)。示例级规则集在文档中给出「先明文再
SSL」等多连接探测——机制要点是:
- L4 通 ≠ L7 通:只开 TCP check 时,监听在但应用卡死的进程仍可能被当成 UP。
- HTTP check 的成功语义偏宽(默认
2xx/3xx):应用返回 404/401 是否算健康,必须用
http-check expect显式收窄,不能靠默认想象。 http-check send-state:可把负载状态告知服务器,与balance first一类「按需点亮机器」的运维闭环配合(见第 7 篇first说明)。
option ssl-hello-chk 等 L6 检查属于「能完成
SSL 握手」层,介于纯 TCP 与完整 HTTP
之间;适合只关心证书/握手路径是否存活、不关心应用 URI
的农场。选哪一层,决定的是假阳性/假阴性落在哪一侧。
三、tcp-check:多步、多端口、可
SSL
option tcp-check +
tcp-check connect|send|expect|...
把探活做成小型脚本:可对多端口依次 connect,可
ssl/sni/alpn,可用字符串或正则
expect,并可用 ok-status /
error-status 区分 L4/L6/L7 成功语义(含条件成功
L7OKC → NOLB 等状态)。
文档约束值得当成机制不变量:
- 规则集需要
connect;通常以connect开头(其前仅允许 set-var / unset-var / comment 等); - 当 server 行既无端口、也无 server port
指令时,必须在序列里用
tcp-check connect port <port>明确目标。
这把「健康」从布尔端口存活,变成可编排的多服务会签:例如同一
server 对象背后既要 POP 又要 IMAP
都就绪。代价是检查更重、失败归因更长——stats/日志里需要靠
tcp-check comment
等把步骤标成人可读原因(本篇不伪造这类输出)。
与数据面关系:tcp-check 再复杂,结果仍是写回 server 状态;它不会在客户端请求路径上同步执行那一整段脚本。
检查与数据面还共享一层资源现实:每个并行 check
占用连接与调度配额。手册中的 tune
项可限制并发检查、在过载时排队延后发起探针,避免探活自己把进程打满。含义是:把
inter
设得很短、农场很大时,失败模式可能先表现为检查风暴,再表现为业务延迟——归因时不要只盯应用
CPU。
四、agent-check:平行控制通道
agent-check(需
agent-port)是独立于常规
health-check 的辅助通道:HAProxy 对 agent 端口建
TCP 连接,读取以 \r 或 \n 结束的
ASCII 行,按空格/制表/逗号切词解析。
手册列出的词义包括(摘要):
| 词 / 形式 | 效果 |
|---|---|
75% 或 weight:… |
调权重(相对初始权或绝对值);0 在 stats
上如 DRAIN |
maxconn:N |
动态改该 server 的 maxconn |
ready / drain /
maint |
管理状态:恢复 / 排空 / 维护 |
up /
down/fail/stopped |
运行状态;up 还需常规 check
也认为可访问才回到 UP |
| 未出现的参数 | 保持原值不变 |
关键边界:
- 连不上 agent
本身不算错误——连通性应由常规
check覆盖。文档警告:agent 报down之后若再把 agent 停掉,可能只剩 agent 报up才能拉回,造成运维死锁。 - 谁改的谁负责撤:agent 进入 DRAIN/DOWN 后,通常期望由 agent(或 CLI 强制)对称恢复;不要假设「TCP check 变绿就会自动取消 agent 的 maint」。
- 与 LB 算法静态性交互:静态算法对可接受的动态权重更严(文档:静态农场上 agent 权重几乎只能是 0 或 100%/初始权)。
Agent 把「应用或侧车进程的意图」注入 HAProxy 的 server 控制面,而常规 check 表达「外部探测是否成功」。二者叠加时,排障必须看哪一个子系统写下了当前状态。
五、与 soft-stop / 排空的交互提示
Starter Guide 强调可把 server 从农场摘掉而不影响既有连接(graceful shutdown 能力)。与检查相关的实践落点:
drain(含 agent 或 Runtime):停新连接(粘滞例外语义见文档),让旧连接自然结束——这是排空,不是探活失败。http-check与 soft-stop 叙事:文档在 http-check 相关段落提到应用可用特定响应配合优雅停机;并把某些响应仍视为 soft-stop 语义。细节以当前 3.4.3 手册对应小节为准,本篇只提示:健康检查可以被设计成「发布通道」,而不只是二进制 UP/DOWN。- 进程 soft-stop(SIGUSR1
等):旧进程停止接新连接并排空;检查任务是否继续、多久退出,与
hard-stop-after、spread-checks 等全局旋钮相关,完整进程交接见 第 12 篇。这里只需记住:reload/soft-stop 窗口里,新旧进程各自跑检查时,短暂的状态不一致可能让外部监控抖动——应用监控应区分「进程交接」与「上游真挂」。
间隔抖动(spread checks)用于降低同硬件多 server 共振;这是调度层面的工程细节,不改变「检查与数据面分离」的模型。
六、disable-on-404:探活当发布开关
http-check disable-on-404(须配合
httpchk):server 对健康检查返回 HTTP
404
时,从负载均衡中排除,但仍接收持久连接;stats
上报 NOLB。若随后再次返回
2xx/3xx,立即回到农场。文档明确这是 Web 管理员做 graceful
shutdown 的方便方法;在此模式下若被判失败,只记 notice
而不当普通告警;与 http-check expect
共用时,404 仍按 soft-stop
语义优先。已因其它原因 stopped 的 server 即使回 404
也保持 stopped;选项只对 running server 求值。
机制上,这把「检查响应码」临时征用为发布/排空信号:应用在下线前对探活
URI 改回 404,边缘自动 NOLB,粘滞连接仍可结束。它与 agent
drain、Runtime drain、进程 soft-stop
同属排空工具箱,但触发源不同——一个是探活观测到的应用响应,一个是控制通道或运维
API,一个是进程信号。
rise/fall、inter、fastinter、downinter
等参数调节「连续成功/失败多少次才翻转状态」以及间隔;它们改变的是状态机迟滞,避免抖动,不把检查合并进数据面请求。观察层(observe)若启用,则把部分真实流量结果反馈进健康判断——那是另一条「被动观察」轴,接近但不等同
Envoy outlier;启用前必须读清当前版本手册,避免把业务 5xx
波动误读成农场震荡。本篇将其列为边界提示,不展开字段百科。
七、谱系、争论与开放问题
谱系:LB 的主动探活从 L4 连通性检查发展到应用层期望匹配,再分出 agent 这类服务器侧推状态通道。Envoy 把主动 HC 与 outlier(被动)并列为两轴(见 Envoy Cluster 篇 与 连接池篇);HAProxy 开源主线上主动 check + agent 更强,被动 outlier 不是同构一等特性——对比时不要误判「没有 outlier 就不会摘除坏主机」(主动 check 与重试/ACL 仍可改变命运)。
争论:探活是否应走与生产完全相同的
TLS/SNI/主机头。完全相同则发现真问题,但检查流量更重、更易被
WAF/限流误伤;简化探活则假阴性上升。文档提供
addr/port/sni
等偏离生产路径的旋钮,本身承认这条权衡。
开放问题:检查风暴与业务尾延迟在共享线程组下的定量隔离(检查是否应更多线程亲和/独立优先级)仍属工程调参区;与外部服务网格主动探测如何去重,是多代理叠层时的开放运维问题。
八、参考资料
规范 / 官方文档(A)
- HAProxy 3.4.3 Configuration
Manual:
option httpchk、http-check *、option tcp-check、tcp-check *、agent-check/agent-port/agent-inter。 - HAProxy 3.4.3 Starter Guide:健康检查与优雅下线相关能力段落。
站内
实验台账
- 本篇无 check 日志实跑片段;不编造 UP/DOWN 翻转时间线。
九、小结
- 检查引擎与数据面请求调度分离:探活改的是候选集,不在客户端路径上同步执行整段探针。
- 默认 TCP check
只证明端口;
httpchk/tcp-check把成功语义推到 L7/多步。 agent-check是平行控制通道,可改权/maxconn/管理状态;连不上 agent ≠ check 失败,但错误使用会造成无法拉回。disable-on-404/ drain / soft-stop 把探活与发布排空叠在同一状态机上;归因时先分「谁写的状态」。- rise/fall 与间隔只调迟滞;观察层若开启则引入近似被动健康信号,需单独评估。
→ 系列目录 · 上一篇:Stick-table · 下一篇:SSL/TLS 路径
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【HAProxy 数据面】Seamless reload 与 soft-stop:FD 交接、排空与状态保留
按 HAProxy 3.4.3 Management Guide 拆解 -x / expose-fd listeners / master-worker sockpair 的 listen FD 交接、SIGUSR1 soft-stop 排空,以及 stick-table/peers 在 reload 下的保留边界;对照 Nginx 与 Envoy hot-restart。
【HAProxy 数据面】排障与可观测:五轴清单与 stats / sess / 日志落点
用 accept/bind、stream/mux、ACL/路由、上游/健康、reload/runtime 五轴组织 HAProxy 生产排障;说明 show info/stat/sess、日志与 stats 页面落在哪一层,不粘贴伪造转储。
【HAProxy 数据面】ACL / 规则引擎:求值顺序、副作用与 stick-table 耦合
把 ACL 与 http-request / use_backend 当作数据面机制:说明连接期到 L7 的求值顺序、动作副作用如何改写后续条件,以及与 stick-table 限流/标记的耦合点;不写 ACL 关键字百科。
【HAProxy 数据面】Backend / server / LB:算法、队列与连接复用边界
把 balance 算法、server maxconn/队列与 http-reuse 当作数据面机制:说明无持久化信息时如何选主、队列满与无 server 时如何失败,并轻对照 Envoy cluster/连接池边界。