HTTP/2通过多路复用和HPACK压缩精准优化TCP连接与TLS握手瓶颈:多路复用使一次TLS握手支撑数十请求,降低连接建立开销;HPACK将头部从KB级压至百字节级,提升传输与解析效率;需ListenAndServeTLS、可信证书、ALPN协商h2及连接复用才生效。

HTTP/2 的多路复用和 HPACK 头部压缩,不是“锦上添花”,而是直接针对 TCP 连接与 TLS 握手这两大性能瓶颈的精准打击——它不减少单次握手耗时,但让一次握手支撑起几十个请求,把开销摊薄到几乎可忽略。
多路复用:一连到底,省掉 90% 的连接建立成本
HTTP/1.1 下,浏览器为并发请求常开 6–8 个 TCP 连接,每个都要经历三次握手 + TLS 握手(含证书交换、密钥协商),在高延迟网络中可能耗时 300ms 以上。HTTP/2 把这些全压进一个连接里:
- 只要服务端启用
ListenAndServeTLS,客户端支持 ALPN(如 Chrome、curl ≥7.47),TLS 握手成功后自动升级为 HTTP/2 - 后续所有请求都复用该连接,走独立 stream,不再新建 TCP 或重做 TLS
- 实测显示:10 个资源并行加载,HTTP/1.1 平均耗时约 420ms;HTTP/2 下降到 180ms 左右,主要节省就来自连接复用
HPACK 压缩:头部从 KB 级干到百字节级,降低传输与解析负担
HTTP/1.1 请求头重复冗余严重(比如每条请求都带完整的 User-Agent、Cookie、Accept),动辄 800–2000 字节。HPACK 通过静态表 + 动态表 + 霍夫曼编码,实现高效压缩:
- 静态表预置 61 个高频字段(如
:method、:path、:authority),用 1–2 字节索引代替完整字符串 - 动态表缓存本次连接中出现过的自定义头(如
Authorization、X-Request-ID),后续相同头只需索引引用 - 典型场景下,请求头体积压缩率达 85%+,从 1.2KB 降至 150 字节以内,既减少带宽占用,也加快 TLS 加密/解密和内核协议栈处理速度
真正生效的关键配置点,缺一不可
Go 默认支持 HTTP/2,但不会自动“生效”。必须同时满足以下条件:
- 服务端必须用
http.ListenAndServeTLS或配置了有效TLSConfig的http.Server——ListenAndServe(纯 HTTP)永远是 HTTP/1.1 - 证书可用且被客户端信任(自签名也可,但 curl 要加
-k,不影响 ALPN 协商) - 客户端 TLS 握手时明确协商出
h2—— 可用openssl s_client -alpn h2 -connect localhost:8080验证 - 多个请求需复用同一连接(如用
http.Client默认 Transport,或浏览器自然行为),单请求独连看不出优势
别踩坑:多路复用 ≠ 自动高性能
协议层优化只是基础,实际性能还卡在你的代码逻辑上:
- Handler 里写
time.Sleep(2 * time.Second)?整个连接上的所有 stream 都会卡住 —— Go HTTP/2 server 是 per-connection goroutine 模型,不是 per-stream 隔离 - 用未设 timeout 的
http.Get调第三方接口?一个慢请求会拖垮同连接所有其他请求 - 动态表大小默认 4KB,若大量短连接频繁创建销毁,反而增加内存抖动;长连接场景建议保持默认,无需手动干预


















