网络请求开销,到底花在哪儿?
做 SDK 接入优化,第一件事就是得搞清楚:一次网络请求,钱都花在哪了。
很多人一上来就调参数、改协议,结果连基础开销都没摸清楚。我见过不少团队,花了大力气优化业务逻辑,结果发现最耗时的反而是网络握手那几步。说白了,地基没打好,上面怎么盖都白搭。
HTTP 协议:远比你想象的重
咱们天天跟 HTTP 打交道,但你真的算过它的开销吗?
先回顾一下 HTTP 的几个版本,看看差别有多大:
| 版本 | 连接方式 | 复用能力 | 典型延迟(理想) | 我见过的坑 |
|---|---|---|---|---|
| HTTP/1.0 | 短连接,一次请求一个 TCP | 无 | 2×RTT + 传输 | 请求多时,光握手就占了 60% 时间 |
| HTTP/1.1 | 持久连接,支持 keep-alive | 队列串行 | 1×RTT + 传输 | 队头阻塞严重,一个慢请求卡住后面所有 |
| HTTP/2 | 多路复用,单一 TCP 连接 | 并行流 | 1×RTT + 传输 | TCP 丢包时,所有流一起受影响 |
| HTTP/3 | 基于 QUIC,UDP 传输 | 独立流,无队头阻塞 | 0-RTT(首次除外) | 有些老旧中间件不支持,得做降级 |
嗯,这里要注意。很多人以为用了 HTTP/2 就万事大吉了。我记得有个项目,团队兴冲冲上了 HTTP/2,结果发现某些弱网环境下,延迟反而比 HTTP/1.1 还高。为什么?因为 TCP 丢包重传会阻塞所有流——你想想看,一个视频流丢包,把旁边的信令请求也卡住了。
核心认知:HTTP 协议本身不产生延迟,但它对底层传输机制的使用方式,决定了延迟的上限。
TCP 三次握手:1.5 个 RTT 的沉默成本
每次建立新连接,TCP 都要来一次「三次握手」。过程不复杂,但开销实实在在:
- 客户端 → 服务器:SYN(同步序列号)
- 服务器 → 客户端:SYN + ACK(确认并同步)
- 客户端 → 服务器:ACK(确认建立)
整个过程,客户端需要等 1.5 个 RTT 才能开始发数据。你算算,如果 RTT 是 100ms,那就是 150ms 的纯开销,还没发任何业务数据呢。
我早年间做过一个广告 SDK,每次启动时要拉取配置。当时没注意,每次请求都新建 TCP 连接,结果用户打开 App 后,光握手就用了 300ms 以上——用户早划走了。后来我把连接池加上,才把延迟压下来。
曾经我踩过一个坑:以为 keep-alive 能解决一切,但没配超时时间。结果连接池里全是半死不活的连接,新请求反而要等超时才能重建。那叫一个痛苦。
TLS 握手:雪上加霜的加密开销
现在 HTTPS 基本是标配了。但你有没有算过,TLS 握手比 TCP 握手要重多少?
以经典的 TLS 1.2 完整握手为例:
- TCP 握手:1.5 RTT
- TLS 握手:2 RTT(ClientHello → ServerHello → 证书 → 密钥交换)
- 合计:3.5 RTT 之后,才能发第一个 HTTP 请求
这还没完,TLS 的证书验证也在握手阶段。我曾经抓包分析过一个海外服务,证书链有 5 级,光把证书数据传完就花了 200ms 的传输时间。
| TLS 版本 | 握手 RTT | 计算开销 | 恢复会话 RTT | 我个人的建议 |
|---|---|---|---|---|
| TLS 1.2 | 2 RTT | 高(尤其 DH 密钥交换) | 1 RTT(Session ID/票证) | 尽量复用会话,减少完整握手 |
| TLS 1.3 | 1 RTT | 较低 | 0 RTT(Early Data) | 强烈推荐升级,但 0-RTT 有重放风险 |
一个小技巧:在 App 启动预热阶段,可以提前做一次 TLS 握手,把 Session Ticket 缓存下来。这样真正发请求时,省掉一个 RTT。
三种协议层综合开销对比
我把上面这些加在一起,算了一笔账。假设 RTT = 80ms,情况如下:
- HTTP + TCP:1.5 RTT = 120ms
- HTTPS + TCP + TLS 1.2:3.5 RTT = 280ms
- HTTPS + TCP + TLS 1.3:2.5 RTT = 200ms
- HTTPS + QUIC (HTTP/3):首次 1 RTT = 80ms
看清了吗?一次 HTTPS 请求,光握手就占了 200ms 以上。如果你的 SDK 里要发生多次请求,这个开销还会累积。
为什么会这样?说白了,TCP 和 TLS 的设计初衷是「可靠」和「安全」,不是「快」。在移动端和弱网环境下,这些设计就显得特别笨重。我们做优化,就是要在这两样东西之间找到平衡点。
给本章画个重点:
- 每个 RTT 都是真金白银的延迟,能省则省
- TCP 三次握手是最基础的沉默成本,用连接池来减少
- TLS 握手是最大的额外开销,优先用 TLS 1.3 和会话复用
- 别盲目升级协议,要结合你的实际网络环境和业务场景