【HAProxy 数据面】Stream 与 Mux:连接之上的协议分层

💡 原文中文,约7400字,阅读约需18分钟。
📝

内容提要

本文介绍HAProxy代理内核中connection、mux、stream三层对象的分工:connection管理传输会话,mux解析线协议,stream执行代理事务。TCP与HTTP路径在mux层分叉,超时配置需区分附着对象(如timeout connect与client/server不同)。排障时先分层归因,再查连接池,避免混淆连接级与流级故障。

🔎

延伸解读

连接、流与事务:三层对象的分工

HAProxy 内核将连接、mux 和 stream 严格分层:connection 管理传输会话,mux 负责解析线协议,stream 执行代理事务。TCP 与 HTTP 路径在 mux 层分叉,TCP 使用 pass-through mux 侧重字节转发,HTTP 则通过 mux_h1/mux_h2 解析并生成 HTX 消息。理解这一分层有助于避免将连接级故障与流级故障混淆,例如 H2 单流 reset 不应视为整连接失败。

超时配置的附着点:别拧错旋钮

timeout 配置看似统一,实则附着在不同对象上:timeout connect 针对上游建连,timeout client/server 针对前后端读写,timeout http-keep-alive 针对事务间隙,timeout tunnel 针对隧道模式。误用时易产生假象,如上游慢却调 client 超时。排障时应将超时问题写成三元组(对象、阶段、角色),并区分连接空闲任务与 stream 上的超时字段。

排障先分层:连接池与流健康

失败归因需先分层再查池:握手后立即断开可能涉及 TLS 或 mux 选错;单请求 503 但连接存活,应检查 stream 级问题;timeout connect 触发需看上游可达性;keep-alive 间隙断开与事务中 server 超时不同。连接健康不等于所有流健康,H2 单流 reset 不应触发整连接重绑。

源码阅读路径:从 stream 与 mux 入手

阅读 HAProxy 源码建议从 src/stream.c 和 src/mux_*.c 入手,理解 stream 生命周期、超时字段及 mux 的协议状态机。先选最小复现(如纯 TCP listen),用 tracing 钉住连接、stream、上游 connect 的次序,再深入 init/attach 路径。避免同时读 H2 窗口与 stick-table,以免混淆三层故障。

Q&A

HAProxy中connection、mux、stream三个对象分别负责什么?

connection管理传输会话,即一条套接字;mux解析线协议,将字节转换为逻辑流;stream执行代理事务,包括分析器、通道和前后端连接器。

TCP和HTTP路径在HAProxy中是如何分叉的?

TCP路径使用pass-through mux(mux_pt),侧重字节转发;HTTP路径使用mux_h1或mux_h2解析协议,解析结果进入HTX,stream执行HTTP规则。

timeout connect和timeout client有什么区别?

timeout connect是建立与服务器连接的时限,timeout client是前端侧等待或空闲超时。误用时,上游慢却拧client,客户端慢却拧server。

如何排查HAProxy中连接级与流级故障?

先分层归因:判断是connection、mux还是stream问题。例如,握手后立即断开可能是TLS或mux选错;单请求503但连接存活可能是stream或上游问题;H2单流reset是流级错误。

HAProxy中stream内部有哪些组件?

stream内部有通道(channel)和连接器(stconn)。通道分为请求和响应方向,分析器按阶段挂在通道上;stconn将stream连接到前后端mux。

在HAProxy源码中,如何定位stream和mux相关代码?

在v3.4.3中,查看src/stream.c和include/haproxy/stream*.h了解stream生命周期;src/mux_pt.c、src/mux_h1.c、src/mux_h2.c查看mux实现;src/stconn*.c和channel相关文件查看连接器与缓冲通道。

🏷️

标签

➡️

继续阅读