这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 网络容量决定最多能承载多少流量,延迟决定用户体感和分布式系统正确性。优化目标不是让单个 curl 达到极限速度,而是让 P99、P999、错误率和成本同时满足 SLO。
31.1 延迟分解
一次 HTTPS 请求:
DNS
+ TCP connect
+ TLS handshake
+ request upload
+ server processing
+ response transfer
+ client render
= total latency
测量:
curl -o /dev/null -s -w \
'dns:%{time_namelookup} connect:%{time_connect} tls:%{time_appconnect} ttfb:%{time_starttransfer} total:%{time_total}\n' \
https://www.example.com
不要只看平均耗时,还要看:
- P50;
- P95;
- P99;
- P999;
- max;
- 错误率;
- 时间序列;
- 分地域分布。
31.2 带宽与吞吐
理论传输时间:
transfer time = response size / bandwidth
实际还受:
- TCP 慢启动;
- RTT;
- 丢包;
- 拥塞窗口;
- 单连接或多连接;
- 服务端处理;
- 队列;
- 中间设备限速。
优化:
- 压缩;
- 减少响应字段;
- 分页;
- CDN;
- 增量加载;
- 合并请求;
- 并行下载;
- 断点续传;
- 就近部署。
31.3 RTT 与请求轮次
跨地域 RTT 示例:
同城 1ms
跨城 30ms
跨洲 150ms
一次跨洲 HTTPS 首次请求可能至少:
DNS + TCP 1RTT + TLS 1RTT + 请求响应 1RTT
优化:
- 长连接;
- TLS 会话恢复;
- HTTP/2 多路复用;
- HTTP/3;
- CDN;
- 就近接入;
- 批量接口;
- 预取;
- 合并依赖。
31.4 缓存
缓存层级:
浏览器
-> Service Worker
-> CDN
-> 网关
-> 应用本地缓存
-> Redis
-> MySQL
设计:
- 静态资源内容哈希;
- HTML 协商缓存;
- 接口按变化频率分级;
- 私有数据禁止公共缓存;
- 缓存 key 明确;
- 失效策略可验证;
- 缓存命中率监控;
- 防雪崩和击穿。
31.5 压缩
| 算法 | 特点 |
|---|---|
| gzip | 兼容性好 |
| br | 压缩率更高,浏览器支持广 |
| zstd | 高压缩率,适合服务间或新生态 |
适合压缩:
- JSON;
- HTML;
- CSS / JS;
- 日志批量传输。
不适合:
- 已压缩图片和视频;
- 小响应体;
- 高 CPU 紧张场景未评估时;
- 流式响应需确认压缩缓冲影响。
31.6 连接复用
短连接成本:
TCP 握手
-> TLS 握手
-> 慢启动
-> 请求
-> 关闭
复用方式:
- HTTP Keep-Alive;
- HTTP/2;
- gRPC 长连接;
- 数据库连接池;
- Redis 连接池;
- 内部 RPC 连接池。
注意:
- 空闲时间小于中间设备超时;
- 借出前健康检查;
- 最大连接数;
- 泄漏检测;
- 优雅关闭;
- DNS 地址刷新;
- 负载再平衡。
31.7 并发与批量
减少延迟:
串行:A 100ms -> B 100ms -> C 100ms,总 300ms
并发:A / B / C 同时执行,总约 100ms
但并发会带来:
- 下游压力;
- 线程切换;
- 连接池竞争;
- 锁竞争;
- 带宽放大;
- 失败扇出。
批量适合:
- 数据库批量查询;
- 缓存 MGET;
- 消息批量发送;
- 日志聚合;
- 外部 API 合并。
批量需要限制:
- 批大小;
- 请求体大小;
- 失败重试粒度;
- 超时时间;
- 内存占用。
31.8 服务端处理优化
网络优化不能掩盖服务端问题:
- 线程池队列;
- 数据库慢查询;
- 下游重试风暴;
- GC 停顿;
- 锁竞争;
- CPU 热点;
- 缓存穿透;
- 大对象序列化;
- 日志阻塞;
- 连接池耗尽。
要建立服务分层耗时:
gateway latency
service latency
db latency
external latency
31.9 容量模型
入口容量:
所需带宽 = 峰值 QPS × 平均响应体 + 平均请求体 + 协议开销
所需并发 = 峰值 QPS × 平均处理时间
连接容量 = 应用实例数 × 每实例连接上限
预留:
- 峰值系数;
- 故障接管容量;
- 重试放大;
- 广播和推送;
- 备份与同步流量;
- 安全攻击余量;
- 发布期间的容量。
31.10 优化决策
优先顺序:
1. 明确 SLO 和当前瓶颈
2. 消除明显错误和重试风暴
3. 减少请求轮次
4. 缓存和压缩
5. 连接复用
6. 就近部署
7. 协议升级
8. 架构拆分
不要为了几毫秒引入复杂系统。每次优化都应有:
- 优化前指标;
- 变更范围;
- 优化后指标;
- 成本变化;
- 风险和回滚;
- 长期监控。
本章小结
延迟优化要拆分 DNS、TCP、TLS、服务处理和传输耗时,并关注分位数和地域差异。常见手段是减少请求轮次、缓存、压缩、批量、并发、连接复用、CDN 和就近部署。容量规划必须考虑峰值、重试放大、故障接管、发布窗口和攻击余量。
思考题
- 一次 HTTPS 请求的延迟包含哪些部分?
- 为什么跨地域系统要减少请求轮次?
- 连接复用需要注意哪些超时问题?
- 如何评估响应压缩的收益?
- 写一个 API P99 从 800ms 到 200ms 的优化方案。