2298 字
约 7 分钟
21
S02-A16 · 加带宽为什么没变快

一个视频站点出口带宽从 1G 扩到 4G,用户反馈"还是卡"。看监控:带宽峰值只用到 1.2G,往返时延没有变化,首帧时间也没变。原因在别处——首帧慢是因为播放器要等一个 2MB 的 manifest 索引,而这个请求走的是另一条有小连接的线路,每次只有 40KB/s。

带宽是"每秒能搬多少",延迟是"第一个字节什么时候到"。用户感知到的是后者,而扩容买的是前者。这是性能问题里最常见的一次买错东西。


1. 两个量在什么情况下各自成为瓶颈

场景 瓶颈
大文件下载、视频传输 带宽
大量小请求、API 调用 延迟
首屏渲染(多次往返) 延迟 × 往返次数
数据库同步、备份 带宽

两个量的关系可以写成一句话:总耗时 ≈ RTT × 往返次数 + 数据量 / 带宽。加带宽只作用在第二项,减往返作用在第一项——而当数据量不大时,第一项占九成。

这个公式还有个用法:把两个数代进去,就知道该优化哪一边。如果 RTT×次数 是 800ms、数据量/带宽是 40ms,那优化顺序一目了然。

第二项与第三项在业务系统里占绝对多数:一个页面有 60 个资源请求,每个 20KB,总数据量 1.2MB,但真正决定加载时间的是每个请求的往返时延乘以串行层数。

2. 为什么加带宽对小请求无效

机制 说明
每请求固定开销 握手、DNS、TLS 不受带宽影响
拥塞窗口增长 小请求在慢启动阶段就结束了
并发连接数限制 带宽再大也只能跑这么多条
队头阻塞 同一连接上的请求互相等

第二项最反直觉:TCP 的传输速率是慢慢涨上去的,一个 20KB 的响应可能在窗口还没涨到满速时就传完了,所以"带宽更大"对它没有任何帮助。

第四项与第三项常一起出现:同一连接上的请求必须按顺序返回,一个慢请求会堵住后面所有请求。这就是为什么"资源不多但页面慢"往往出自某一个慢接口。

第三项在 HTTP/1.1 时代是硬约束:浏览器对同一域名只开 6 条连接,第 7 个请求必须排队。带宽翻四倍,队列长度不变。

// 一个 20KB 资源在两种带宽下的耗时(RTT 40ms,忽略慢启动)
带宽 10Mbps:传输 16ms + RTT 40ms ≈ 56ms
带宽 100Mbps:传输 1.6ms + RTT 40ms ≈ 42ms
// 带宽翻 10 倍,耗时只降 25% —— 因为 RTT 是常数项

3. 延迟的四个组成部分

组成 可否优化
传播延迟(物理距离) 只能靠就近部署
传输延迟(数据量/带宽) 加带宽、减体积
排队延迟(拥塞) 减少并发、加容量
处理延迟(服务端计算) 优化代码与查询

四个组成里,只有"排队延迟"会随时间剧烈波动:同一链路在高峰与低谷可能差十倍,而其余三项基本稳定。所以"白天慢晚上快"这类现象几乎总能归到排队。

第一项最容易被忽略:跨洲的 RTT 是物理定律,光纤里每 1000 公里约 5ms 单程。北京到法兰克福往返约 180ms,任何带宽都无法改善。

第三项是"带宽够但延迟高"的常见原因:链路拥塞时数据包排队,此时扩容有效,但要看是"链路拥塞"还是"服务端排队"——后者加带宽无用。

4. 真正有效的四类手段

手段 作用对象
减少请求数(合并、内联) 往返次数
就近部署(CDN、多区域) 传播延迟
连接复用(keep-alive、HTTP/2) 握手与队头阻塞
减少体积(压缩、按需) 传输延迟

减请求数还有个"零成本"版本:去掉根本没人看的资源。埋点、旧版兼容脚本、重复引入的库,在三年积累的页面里通常占三成——这类删除不改变功能,只减少往返。

第一项的收益通常最大:60 个请求减到 15 个,等效于把延迟降到四分之一——而任何带宽升级都做不到这一点。

就近部署的收益可以用一个数估出来:每 1000 公里约 5ms 单程,往返翻倍。把服务从一地扩到三地(每地覆盖 1000 公里半径),对远端用户是 30ms 以上的净收益,而这是纯带宽买不到的。

// 就近部署的收益估算(单程 5ms / 1000km)
距离 3000km:单程 15ms,RTT 30ms
距离 300km :单程 1.5ms,RTT 3ms
// 每个串行请求省 27ms;10 层串行就省 270ms

第三项在 HTTP/2 下解决了队头阻塞(同一连接多路复用),但引入了新的约束:单连接上的流数有上限,超过后仍会排队。

// 三件低成本的事:连接复用、压缩、就近
keepalive_timeout 65;
gzip on;
gzip_types text/css application/javascript application/json;
// 静态资源交给 CDN,源站只保留动态请求

5. 怎么判断该加带宽还是降延迟

观察 结论
带宽利用率 > 70% 且延迟升高 加带宽
带宽利用率 < 30% 但延迟高 查延迟,别加带宽
单请求体积大、数量少 加带宽或压缩
请求多、体积小 减请求数、就近部署

第一项与第二项的差别就是开头那个案例:带宽只用到 30%,扩容必然无效。这条判据简单到可以在值班手册里写一句。

// 先量三个数:带宽利用率、RTT、每页请求数
sar -n DEV 1 5 | awk '/eth0/ {print $5*8/1e6 " Mbps in"}'
ping -c 20 target | tail -2                     # RTT 与抖动
curl -s -w '%{time_connect} %{time_starttransfer} %{size_download}\n' -o /dev/null URL
// 三个数一起看,才知道瓶颈在带宽还是在往返

6. 排错:五种"扩容后没变化"

现象 成因 处理方向
带宽利用率没涨 瓶颈不在带宽 查 RTT 与请求数
首屏没变快 关键路径是串行往返 减依赖层级
单用户快、并发时慢 服务端排队 查后端而非网络
部分用户仍慢 就近部署没覆盖 查 CDN 命中与线路
传输大文件仍慢 单连接窗口限制 多连接或调窗口

排查时还应当区分"用户感知"与"指标":首字节时间(TTFB)反映服务端,加载完成时间反映网络与渲染。两个指标一起看,能立刻分辨是"后端慢"还是"传输慢"。

// 拆分三段耗时:连接、首字节、整体
curl -s -o /dev/null -w 'dns=%{time_namelookup} conn=%{time_connect} ttfb=%{time_starttransfer} total=%{time_total}
' URL
// conn 大 → 网络/握手;ttfb-conn 大 → 服务端;total-ttfb 大 → 传输/体积

第二项是最常见的误判:"首屏慢"被当成"网络慢",实际是关键路径上串了四个接口,每个 200ms——加带宽一分钱效果都没有。

7. 边界:什么情况带宽确实是答案

场景 为什么 做法
视频、大文件分发 数据量主导 加带宽或上 CDN
备份与同步 吞吐主导 加带宽或压缩
内网批量传输 RTT 很小 带宽几乎是唯一变量
出口被限速 硬上限 扩容直接有效

判断口径一句话:这次慢,是"每秒搬得少"还是"第一字节来得晚"。前者加带宽,后者减往返、就近部署、复用连接。


8. 自测

  1. 带宽与延迟分别主导哪类场景?为什么业务系统里多数是后者?
  2. 为什么"一个 20KB 的响应"从加带宽中获益很小?慢启动在其中起什么作用?
  3. HTTP/1.1 的连接数限制如何让带宽扩容失效?HTTP/2 解决了什么、又带来什么新约束?
  4. 延迟的四个组成部分里,哪一项完全无法通过带宽改善?为什么?
  5. 判断"该加带宽还是降延迟"的两个观察是什么?为什么"带宽利用率 < 30% 但延迟高"能直接排除扩容?
  6. 判断口径的那个问题是什么?
S02-A16 · 加带宽为什么没变快
https://www.clxhxhhr.top/posts/6449/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。