Computer NetworkNotes

第 31 章:容量与延迟优化

zjc 于 2026-01-31 发布

这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 网络容量决定最多能承载多少流量,延迟决定用户体感和分布式系统正确性。优化目标不是让单个 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

不要只看平均耗时,还要看:

  1. P50;
  2. P95;
  3. P99;
  4. P999;
  5. max;
  6. 错误率;
  7. 时间序列;
  8. 分地域分布。

31.2 带宽与吞吐

理论传输时间:

transfer time = response size / bandwidth

实际还受:

  1. TCP 慢启动;
  2. RTT;
  3. 丢包;
  4. 拥塞窗口;
  5. 单连接或多连接;
  6. 服务端处理;
  7. 队列;
  8. 中间设备限速。

优化:

  1. 压缩;
  2. 减少响应字段;
  3. 分页;
  4. CDN;
  5. 增量加载;
  6. 合并请求;
  7. 并行下载;
  8. 断点续传;
  9. 就近部署。

31.3 RTT 与请求轮次

跨地域 RTT 示例:

同城 1ms
跨城 30ms
跨洲 150ms

一次跨洲 HTTPS 首次请求可能至少:

DNS + TCP 1RTT + TLS 1RTT + 请求响应 1RTT

优化:

  1. 长连接;
  2. TLS 会话恢复;
  3. HTTP/2 多路复用;
  4. HTTP/3;
  5. CDN;
  6. 就近接入;
  7. 批量接口;
  8. 预取;
  9. 合并依赖。

31.4 缓存

缓存层级:

浏览器
  -> Service Worker
     -> CDN
        -> 网关
           -> 应用本地缓存
              -> Redis
                 -> MySQL

设计:

  1. 静态资源内容哈希;
  2. HTML 协商缓存;
  3. 接口按变化频率分级;
  4. 私有数据禁止公共缓存;
  5. 缓存 key 明确;
  6. 失效策略可验证;
  7. 缓存命中率监控;
  8. 防雪崩和击穿。

31.5 压缩

算法 特点
gzip 兼容性好
br 压缩率更高,浏览器支持广
zstd 高压缩率,适合服务间或新生态

适合压缩:

  1. JSON;
  2. HTML;
  3. CSS / JS;
  4. 日志批量传输。

不适合:

  1. 已压缩图片和视频;
  2. 小响应体;
  3. 高 CPU 紧张场景未评估时;
  4. 流式响应需确认压缩缓冲影响。

31.6 连接复用

短连接成本:

TCP 握手
  -> TLS 握手
     -> 慢启动
        -> 请求
           -> 关闭

复用方式:

  1. HTTP Keep-Alive;
  2. HTTP/2;
  3. gRPC 长连接;
  4. 数据库连接池;
  5. Redis 连接池;
  6. 内部 RPC 连接池。

注意:

  1. 空闲时间小于中间设备超时;
  2. 借出前健康检查;
  3. 最大连接数;
  4. 泄漏检测;
  5. 优雅关闭;
  6. DNS 地址刷新;
  7. 负载再平衡。

31.7 并发与批量

减少延迟:

串行:A 100ms -> B 100ms -> C 100ms,总 300ms
并发:A / B / C 同时执行,总约 100ms

但并发会带来:

  1. 下游压力;
  2. 线程切换;
  3. 连接池竞争;
  4. 锁竞争;
  5. 带宽放大;
  6. 失败扇出。

批量适合:

  1. 数据库批量查询;
  2. 缓存 MGET;
  3. 消息批量发送;
  4. 日志聚合;
  5. 外部 API 合并。

批量需要限制:

  1. 批大小;
  2. 请求体大小;
  3. 失败重试粒度;
  4. 超时时间;
  5. 内存占用。

31.8 服务端处理优化

网络优化不能掩盖服务端问题:

  1. 线程池队列;
  2. 数据库慢查询;
  3. 下游重试风暴;
  4. GC 停顿;
  5. 锁竞争;
  6. CPU 热点;
  7. 缓存穿透;
  8. 大对象序列化;
  9. 日志阻塞;
  10. 连接池耗尽。

要建立服务分层耗时:

gateway latency
service latency
db latency
external latency

31.9 容量模型

入口容量:

所需带宽 = 峰值 QPS × 平均响应体 + 平均请求体 + 协议开销
所需并发 = 峰值 QPS × 平均处理时间
连接容量 = 应用实例数 × 每实例连接上限

预留:

  1. 峰值系数;
  2. 故障接管容量;
  3. 重试放大;
  4. 广播和推送;
  5. 备份与同步流量;
  6. 安全攻击余量;
  7. 发布期间的容量。

31.10 优化决策

优先顺序:

1. 明确 SLO 和当前瓶颈
2. 消除明显错误和重试风暴
3. 减少请求轮次
4. 缓存和压缩
5. 连接复用
6. 就近部署
7. 协议升级
8. 架构拆分

不要为了几毫秒引入复杂系统。每次优化都应有:

  1. 优化前指标;
  2. 变更范围;
  3. 优化后指标;
  4. 成本变化;
  5. 风险和回滚;
  6. 长期监控。

本章小结

延迟优化要拆分 DNS、TCP、TLS、服务处理和传输耗时,并关注分位数和地域差异。常见手段是减少请求轮次、缓存、压缩、批量、并发、连接复用、CDN 和就近部署。容量规划必须考虑峰值、重试放大、故障接管、发布窗口和攻击余量。

思考题

  1. 一次 HTTPS 请求的延迟包含哪些部分?
  2. 为什么跨地域系统要减少请求轮次?
  3. 连接复用需要注意哪些超时问题?
  4. 如何评估响应压缩的收益?
  5. 写一个 API P99 从 800ms 到 200ms 的优化方案。