Tengine XQUIC 开启 reuseport 后 HTTP/3 不稳定问题排查总结 一、问题概况Tengine 启用 XQUIC/HTTP/3 后UDP 443 监听一旦配置reuseportChrome 访问主页面时 HTTP/3 只能偶发成功连续刷新后通常回退到 HTTP/2少数情况下仅/favicon.ico等后续资源使用 HTTP/3。移除reuseport后现象明显缓解。初始环境为 Tengine 3.1.0、XQUIC 1.8.0、Tongsuo 8.3.2、Chrome 150.0.7871.187服务端采用worker_processes auto。最初怀疑reuseport与多 worker 分流、CID 路由或 UDP socket 使用方式存在冲突。经四轮控制变量实验和日志比对最终确认该现象由两个相互独立的问题叠加造成。二、结论一HTTP/3 连接关闭的根因旧版 XQUIC 的 CID 下发和计数逻辑与 Chrome 的实现不兼容。Chrome 未通告active_connection_id_limit时默认上限为 2旧版 XQUIC 在握手 CID 之外又发送两个NEW_CONNECTION_ID序号分别为 1、2且retire_prior_to均为 0。Chrome 将握手 CID 一并计数认为当前持有 3 个 CID超过上限随即发送CONNECTION_ID_LIMIT_ERRORPeer provides more connection IDs than the limit. quic_error: 203 quic_wire_error: 9服务端对应记录为err:0x9 close_msg:remote error|addr or cid not availHTTP/3 请求和响应实际上已经完成但连接随后被关闭不能供后续导航复用因此 Chrome 在后续请求中回退到 HTTP/2。该问题由 XQUIC PR #821 修复对应提交为782e80c。修复后服务端每个会话只发送一个额外 CIDChrome 持有的 CID 总数不再超过默认上限。二多 worker 下 0-RTT 不稳定的原因未显式配置共享 Session Ticket Key 和 Token Key 时默认相对路径的 key 文件读取失败各 worker 会分别生成随机 key。一个 worker 签发的 ticket 或 token 无法由其他 worker 校验导致多 worker、reuseport场景下 0-RTT 和 token 验证不稳定。显式配置所有 worker 共享的绝对路径后该问题得到解决xquic_ssl_session_ticket_key /opt/soft/nginx/ssl/xquic_session_ticket.key; xquic_token_key_file /opt/soft/nginx/ssl/xquic_token.key;这一问题会放大多 worker 场景下的异常表现但不是 Chrome 以0x09关闭连接的根因。三已排除因素四轮实验表明CID 超限错误与下列因素无直接因果关系reuseport本身worker 数量及跨 worker 分流accept_mutexIPv4/IPv6 双栈配置Tengine 的xquic_cid_route“每个 QUIC 连接单独创建 UDP socket”的假设。其中reuseport和多 worker 会使连接恢复及 0-RTT 问题更明显但不能解释单 worker 下同样出现的 CID 超限错误。三、排查过程一实验一核查 worker 数量与 reuseport 的关系第一轮实验保持 IPv4 和reuseport不变将worker_processes分别设置为 1、2、4观察 HTTP/3 请求、0-RTT 和连接关闭情况。worker 数量Chrome QUIC 会话Chrome CID 超限关闭服务端err:0x9主要现象1444H3 和 0-RTT 表现相对较好但连接仍被关闭2222H3 成功率下降连接仍被关闭4333H3 不稳定连接仍被关闭Chrome NetLog 在三组测试中均显示每个会话收到序号 1、2 两个额外 CID随后报Peer provides more connection IDs than the limit.。服务端的err:0x9与浏览器关闭事件逐一对应。本轮结果说明多 worker 会影响 H3 和 0-RTT 的实际表现但不是连接关闭的必要条件即使只有一个 worker问题仍可稳定复现。排查重点因此由 worker 分流转向 Chrome 主动关闭连接的具体原因。二实验二排除 accept_mutex 和 IPv6 影响第二轮实验采用worker_processes auto和reuseport关闭accept_mutex分别测试 IPv4IPv6 双栈和仅 IPv4 两种配置。配置Chrome QUIC 会话Chrome CID 超限关闭服务端err:0x9IPv4IPv6、accept_mutex off222仅 IPv4、accept_mutex off222两种配置下的结果完全一致Chrome 均收到序号 1、2 两个额外 CID并以quic_wire_error: 9关闭连接。由此可以排除accept_mutex和 IPv4/IPv6 双栈不对称。由于精简监听和事件配置后问题仍在排查范围进一步收敛到 CID 生成、下发和计数逻辑。三实验三关闭 CID 路由并配置共享 key第三轮实验统一采用 IPv4、reuseport、accept_mutex off增加以下配置xquic_cid_route off; xquic_ssl_session_ticket_key /opt/soft/nginx/ssl/xquic_session_ticket.key; xquic_token_key_file /opt/soft/nginx/ssl/xquic_token.key;同时对比worker_processes 1与worker_processes auto。worker 配置Chrome QUIC 会话Chrome CID 超限关闭服务端err:0x90-RTT/Token1444可见 0-RTT 接受及 token 校验成功auto1099共享 key 后表现改善但 CID 错误仍在本轮继续观察到旧版 XQUIC 对每条连接发送两个额外 CID序号为 1、2关闭xquic_cid_route后行为没有变化单、多 worker 均出现同一错误。至此可以确认CID 超限并非 Tengine CID 路由造成而是 XQUIC 库自身的 CID 下发逻辑所致。另一方面共享 Session Ticket Key 和 Token Key 后0-RTT 与 token 验证恢复浏览器中更容易出现 HTTP/3但连接仍会因 CID 超限而关闭。这也证明 0-RTT 问题与 CID 问题相互独立。结合 XQUIC Issue #820、PR #821 及提交782e80c维护者进一步确认该修复直接覆盖“XQUIC 服务端对接 Chrome 客户端”的场景。随后进入新版本验证阶段。四实验四使用 XQUIC main 分支复测第四轮使用包含 PR #821 修复的 XQUICmain分支重新编译测试。环境更新为 Tengine 3.2.0、Nginx core 1.31.3、Tongsuo 8.3.2、Chrome 151.0.0.0保留reuseport现场生效配置为worker_processes 1。本轮重点验证新旧 XQUIC 的 CID 下发行为变化。复测结果如下连续刷新记录到 10 个成功的 HTTP/3 请求每个新 QUIC 会话只收到一个额外 CID即sequence_number: 1Chrome NetLog 中不再出现QUIC_CONNECTION_ID_LIMIT_ERROR和Peer provides more connection IDs than the limit服务端不再出现err:0x9连接最终以err:0x0或 idle timeout 正常结束未再出现首次访问正常、刷新后回退 HTTP/2 的问题。新版本将额外 CID 数量由两个降为一个Chrome 持有的 CID 总数保持在默认上限内旧版中的完整错误链路随之消失。实验结果与 PR #821 的修复目标一致Issue 根因和解决方案得到验证。四、处理建议XQUIC 应使用包含 PR #821、提交782e80c的版本不建议继续使用 XQUIC 1.8.0或仅升级到不包含该修复的旧 release。多 worker 环境应显式配置所有 worker 共享且可读的 Session Ticket Key 和 Token Key避免 0-RTT 与 token 校验跨 worker 失败。xquic_cid_route off不能解决 CID 超限问题可按业务需要恢复默认设置。同一地址和端口的相关 listener 应统一reuseport配置避免引入额外的监听行为差异。后续应在worker_processes auto reuseport的实际生产配置下补充长时间、较高并发验证并记录所用 XQUIC 的准确 commit便于版本追踪和回归测试。五、总体判断本次问题表面上与reuseport高度相关实际是旧版 XQUIC 的 CID 兼容性缺陷与多 worker 共享 key 配置缺失共同作用的结果。前者导致 Chrome 主动关闭 QUIC 连接是 HTTP/3 刷新后回退 HTTP/2 的直接原因后者导致 0-RTT 和 token 校验不稳定放大了多 worker 场景下的异常表现。采用包含782e80c的 XQUICmain分支并配置共享 Session Ticket Key 和 Token Key 后CID 超限错误消失HTTP/3 连续请求恢复正常。Issue #2074 的核心问题已完成定位和初步验证。