Files
go-omni/transport/native/HTTP2.md

4.5 KiB
Raw Blame History

native HTTP/2 进入条件

当前 transport/native 是经过 Linux 长连接和反向代理验收的 HTTP/1.1 实现。HTTP/2 暂不直接打开,原因是它把一个 TCP 连接变成多个独立请求流,连接级的 Keep-Alive、超时和并发限制不能直接复用现有 HTTP/1.1 状态机。

当前已提供独立的 transport/http2 实验 Runner。它已经验证 TLS/h2、h2c、本地连接和请求闸门、GOAWAY 排空以及 RST_STREAM 取消;这些结果用于验证生命周期设计,不代表 native 已经启用 HTTP/2。实验 Runner 还覆盖了默认 1 MiB 头部上限、8 MiB 请求体上限、128 路同连接 stream 多路复用,以及 2 MiB 慢读取 body 在窗口耗尽后的恢复。TestTLSSoak 默认运行 3 秒,Linux 长测通过 python3 scripts/verifyHTTP2.py --duration 30m 启动。

目标边界

  • HTTP/2 必须作为显式 opt-in 协议,不改变 omni.New()、transport/nethttp 或 native HTTP/1.1 的默认行为。
  • TLS ALPN 只在 HTTP/2 实现通过全部验收后增加 h2;当前 native 只宣告 http/1.1,误配 h2 会在启动时失败。
  • Handler、Service、统一响应、requestId、可信代理和业务日志继续复用现有 httpx.Context 与 http.Handler 边界。
  • h2c 只用于本地测试,生产入口使用 TLS + ALPN;不能把明文升级路径默认为公网协议。

连接和流的生命周期

  1. accept loop 先执行连接上限检查,再执行 TLS 握手;握手受独立超时约束,不能占满连接槽位后无限等待。
  2. TLS 协商得到 h2 后进入 HTTP/2 connection state;其他 ALPN 直接关闭,不能把 HTTP/2 preface 交给 HTTP/1.1 解析器。
  3. 每个 stream 创建独立的 http.Request 和取消 context。RST_STREAM 只取消当前请求,TCP 断开才取消该连接上的所有请求。
  4. MaxConcurrentRequests 是所有连接共享的全局请求闸门;MaxConcurrentStreams 限制单连接并发流;两者都必须在收到完整请求体前生效。
  5. MaxHeaderBytes 沿用标准库默认 1 MiB 上限,MaxBodyBytes 默认限制请求体为 8 MiB;已声明超限的请求在进入业务 handler 前返回 413,未声明长度的 body 通过受限 reader 读取,避免业务层无意间把整个请求体加载到内存。
  6. 服务关闭时停止 accept,发送 GOAWAY 拒绝新流,等待活动流排空;超过 ShutdownTimeout 后关闭连接并取消剩余请求。实验 Runner 已覆盖这条顺序。

必须可观测的状态

HTTP/2 版本需要在 native Stats 之外至少记录:活动 stream、被拒绝 stream、连接级 protocol error、RST_STREAM、GOAWAY 发送次数,以及因流控或并发闸门触发的拒绝。实验 Runner 当前已通过 ActiveRequests、RejectedRequests、ProtocolErrors、RSTStreams、GoAwaySent 和 GoAwayFrames 暴露活动/拒绝/协议错误/客户端重置/优雅关闭快照;帧观察器只解析 9 字节头部并跳过 payload,不会缓存大 body。计数必须是原子快照,不能在 metrics handler 中锁住连接状态机。

进入实现前的验收矩阵

  • TLS ALPN:只协商 h2,HTTP/1.1 客户端仍由现有 native 路径处理;不支持的 ALPN 在握手前后都不会误入错误解析器。
  • 多路复用:一个连接并发至少 128 个 stream,响应和 requestId 不串线,单个慢 stream 不阻塞其他 stream(实验 Runner 已覆盖 128 路同连接 stream)。
  • 流控:慢读取、慢写、窗口耗尽和大 body 都能恢复;内存不会随未消费 body 无限增长(实验 Runner 已覆盖 2 MiB 慢读取 body 和请求体上限)。
  • 取消:RST_STREAM、客户端断开、服务关闭分别只影响应受影响的请求,并能在 metrics 中看到回收;当前实验 Runner 已覆盖 RST_STREAM 与服务关闭。
  • 背压:连接上限、全局 stream 上限、单连接 stream 上限和 header/body 上限均能快速拒绝并自动恢复。
  • 代理联调:Nginx/Cloudflare 的 TLS、Keep-Alive、超时、GOAWAY 和优雅发布行为与 HTTP/1.1 回源结果一致。
  • 长测:Linux amd64 至少 30 分钟 TLS、多连接、多 stream、慢客户端混合场景;要求 0 协议错误、0 请求串线,连接、stream、goroutine 和 FD 在停止后回收。

只有上述矩阵完成,才把 h2 加入 native 的 TLS ALPN,并考虑把 HTTP/2 作为独立版本能力发布。此前生产环境使用 Nginx/Cloudflare 终止 HTTP/2 后以 HTTP/1.1 回源,或使用支持 HTTP/2 的 transport/nethttp。