网络性能
→ 返回 计算机网络
“网速好慢” 背后其实是两件完全不同的事:带宽决定了数据的上限,延迟决定了反应的快慢。很多时候让人烦躁的卡顿,不是带宽不够,而是延迟太高。
带宽、网速与延迟
带宽(Bandwidth)
带宽是网络链路的最大吞吐能力,单位是 bps(比特每秒)。
带宽好比高速公路的车道数:
2 车道 ←→ 100 Mbps 宽带
8 车道 ←→ 1000 Mbps(千兆)宽带
车道多,单位时间能跑的车(数据)就多。
家用宽带套餐标注的 “500M” 指 500 Mbps,换算为字节是 500 ÷ 8 ≈ 62 MB/s 的理论下载上限。实际速度受线路质量、服务器带宽、路由拥塞等因素影响,通常达不到峰值。
延迟(Latency)与 RTT
延迟是数据从源头到目标所需的单程时间,通常用 RTT(Round-Trip Time,往返时延)衡量,单位毫秒(ms)。
RTT = 数据发出 → 到达目标 → 响应回来 的总时间
ping www.example.com
64 bytes from 93.184.216.34: time=120ms ← RTT = 120ms
延迟取决于:
| 因素 | 说明 |
|---|---|
| 物理距离 | 光速约 20 万 km/s(光纤折射率约 2/3 光速),北京→纽约约 80ms 理论下限 |
| 路由跳数 | 每经过一台路由器增加约 0.5~5ms |
| 拥塞 | 路由器队列满时排队等待 |
| 服务器处理时间 | 数据库查询、计算逻辑耗时 |
带宽 vs 延迟:哪个更重要?
下载 1GB 文件 —— 带宽是瓶颈
100 Mbps:≈ 80 秒
1000 Mbps:≈ 8 秒
打开一个网页 —— 延迟是瓶颈
每次 HTTP 请求至少 1 个 RTT
HTTPS 首次连接:DNS(1RTT) + TCP(1RTT) + TLS(1~2RTT) + HTTP(1RTT) = 4~5 RTT
RTT=50ms:≈ 200~250ms
RTT=200ms:≈ 800ms~1s
结论: 加载静态大文件看带宽;网页交互、API 响应看延迟。延迟无法靠提升带宽解决。
打开一个网页:完整链路
在浏览器地址栏输入 https://example.com 按回车,到页面显示出来,经历了以下步骤:
[浏览器]
│
▼ Step 1: DNS 解析
│ example.com → 93.184.216.34
│ (浏览器缓存 → OS缓存 → 本地DNS → 根/顶级/权威DNS)
│ 耗时:0~200ms(有缓存则 <1ms)
│
▼ Step 2: TCP 三次握手
│ SYN → SYN+ACK → ACK
│ 耗时:1 RTT(约 20~200ms,取决于服务器距离)
│
▼ Step 3: TLS 握手(HTTPS)
│ ClientHello → ServerHello+证书 → 密钥交换 → Finished
│ 耗时:1~2 RTT(TLS 1.3 为 1 RTT,TLS 1.2 为 2 RTT)
│
▼ Step 4: HTTP 请求
│ GET / HTTP/1.1
│ 耗时:1 RTT + 服务端处理时间
│
▼ Step 5: 接收响应 & 渲染
HTML → CSS/JS/图片(并发子请求)→ 页面渲染
耗时:取决于资源大小和数量
量化示例(服务器在上海,用户在北京,RTT ≈ 30ms):
| 步骤 | 耗时 |
|---|---|
| DNS 解析(无缓存) | ~50ms |
| TCP 握手 | 30ms(1 RTT) |
| TLS 1.3 握手 | 30ms(1 RTT) |
| HTTP 请求+响应 | 30ms + 服务端处理 |
| 合计(TTFB) | ≈ 140ms~200ms |
TTFB(Time to First Byte):从发起请求到收到响应第一个字节的时间,是衡量服务端响应速度的核心指标。
DNS 解析详解
访问任何域名前,必须先把域名翻译成 IP,这一过程叫 DNS 解析。
浏览器输入 www.example.com
│
▼ ① 浏览器 DNS 缓存(命中则结束,<1ms)
▼ ② 操作系统缓存 + hosts 文件
▼ ③ 本地 DNS 解析器(通常是路由器,转发给运营商)
▼ ④ 根域名服务器(. 告诉你去问 .com 服务器)
▼ ⑤ 顶级域名服务器(.com 告诉你去问 example.com 的服务器)
▼ ⑥ 权威域名服务器(返回最终 IP:93.184.216.34)
│
└── 各级结果按 TTL 缓存,下次命中缓存跳过多步
DNS 解析的延迟来源:
- 国内访问国外 DNS 服务器:50~200ms
- 运营商递归解析器繁忙
- TTL 过短导致频繁重新解析
优化手段:
- 使用快速公共 DNS(
114.114.114.114、8.8.8.8、1.1.1.1) - 合理设置 TTL(稳定记录用较大 TTL,如 3600s)
- CDN 智能 DNS 就近调度
- 浏览器 DNS 预解析:
<link rel="dns-prefetch" href="//api.example.com">
TCP 三次握手:为什么需要”三次”
TCP 建立连接前必须双方确认各自的发送和接收能力都正常。
客户端 服务端
│ │
│── ① SYN(我想连接你)─────────►│ 服务端知道:客户端能发
│ │
│◄─ ② SYN+ACK(好的,我也想连)──│ 客户端知道:自己能发/收,服务端能发/收
│ │
│── ③ ACK(收到)───────────────►│ 服务端知道:客户端能收
│ │
│ 连接建立 │
为什么不能两次握手? 两次握手服务端无法确认客户端是否收到了 SYN+ACK,且无法防止旧的 SYN 报文(网络延迟存活)误建连接。
三次握手的代价: 每次新建 TCP 连接固定消耗 1 RTT。HTTP/1.1 通过 Keep-Alive 复用连接,HTTP/2 多路复用,HTTP/3(QUIC)则进一步将握手合并到 TLS,实现 0-RTT 恢复。
详见 TCP。
TLS 握手:HTTPS 的代价
HTTPS 在 TCP 之上加了 TLS 层,保证数据加密传输。但加密是有代价的:
TCP 连接建立后:
TLS 1.2(2 RTT):
客户端 服务端
│── ClientHello ─────────────►│
│◄─ ServerHello + 证书 ────────│ ← 1 RTT
│── 密钥交换 ─────────────────►│
│◄─ 握手完成 ──────────────────│ ← 2 RTT
│ 开始加密传输 │
TLS 1.3(1 RTT):
客户端 服务端
│── ClientHello + 密钥参数 ───►│
│◄─ ServerHello + 证书 + 完成──│ ← 1 RTT
│ 开始加密传输 │
TLS 握手做了什么:
- 验证服务端身份(证书链 → CA 签名验证)
- 协商加密算法
- 安全交换对称密钥(用非对称加密保护交换过程)
- 之后数据用对称密钥(AES)加密,速度快
性能影响:
- TLS 1.2:额外增加 2 RTT
- TLS 1.3:额外增加 1 RTT(已成为主流)
- 会话恢复(Session Resumption):已访问过的站点可 0-RTT 恢复,无额外握手
详见 TLS。
延迟的来源与优化
延迟分解
用户感知的"慢" = DNS延迟 + TCP握手 + TLS握手 + 服务端处理 + 传输时间 + 渲染时间
│←────────── TTFB ──────────►│←── 传输+渲染 ──►│
| 延迟来源 | 典型耗时 | 优化方向 |
|---|---|---|
| DNS 解析 | 0~200ms | DNS 预解析、合理 TTL、快速 DNS 服务 |
| TCP 握手 | 1 RTT | Keep-Alive 复用、HTTP/2、CDN 就近 |
| TLS 握手 | 1~2 RTT | TLS 1.3、Session 复用(0-RTT) |
| 服务端处理 | 几ms~几秒 | 缓存、数据库优化、异步处理 |
| 数据传输 | 取决于大小+带宽 | 压缩(gzip/brotli)、减少资源体积 |
| 渲染 | 取决于资源数量 | 减少请求数、懒加载、预加载 |
CDN 加速的本质
CDN 将内容缓存到离用户最近的边缘节点:
用户(北京)→ CDN 节点(北京):RTT ≈ 5ms
用户(北京)→ 源站(美国) :RTT ≈ 180ms
对于静态资源(图片/JS/CSS),命中 CDN 缓存相当于把服务器"搬"到用户旁边。
详见 CDN。
如何测量网络性能
ping:测量 RTT
ping example.com
# ICMP 包往返时间,反映基础延迟
# time < 20ms:极好 20~50ms:良好 50~150ms:正常 >150ms:较慢traceroute:追踪路由路径
traceroute example.com # Linux/macOS
tracert example.com # Windows
# 输出每一跳路由器及对应延迟
# 1 192.168.1.1 1ms ← 本地路由器
# 2 10.0.0.1 5ms ← 运营商
# 3 ...
# 10 93.184.216.34 120ms ← 目标通过 traceroute 能定位延迟集中在哪一段链路。
curl:分解 HTTP 请求各阶段耗时
curl -o /dev/null -s -w "
DNS 解析: %{time_namelookup}s
TCP 握手: %{time_connect}s
TLS 握手: %{time_appconnect}s
首字节时间(TTFB):%{time_starttransfer}s
总耗时: %{time_total}s
" https://example.com浏览器 DevTools:Network 面板
Request URL: https://example.com
Timing:
Queueing: 0.5ms
DNS Lookup: 12ms ← DNS 解析
Initial connection: 28ms ← TCP 握手
SSL: 26ms ← TLS 握手
TTFB: 85ms ← 服务端处理
Content Download: 5ms ← 数据传输
常见网络问题排查
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 页面打开慢,其他网站正常 | 服务器响应慢 / CDN 节点异常 | curl 看 TTFB;换 DNS 测试 |
| 所有网站都慢 | 本地网络或运营商问题 | ping 8.8.8.8;traceroute |
| 图片/JS 加载慢 | 静态资源未用 CDN | DevTools 查看资源来源 |
| 首次打开慢,刷新快 | DNS 缓存冷启动 / TLS 会话未复用 | DNS 预解析;HSTS preload |
| 时快时慢 | 路由拥塞 / 服务端负载不稳定 | 多次 ping 看抖动(Jitter) |
| HTTPS 比 HTTP 慢很多 | TLS 握手代价 / 证书验证慢 | 启用 OCSP Stapling;升级 TLS 1.3 |
网络性能关键指标速查
| 指标 | 英文 | 含义 | 工具 |
|---|---|---|---|
| 带宽 | Bandwidth | 链路最大吞吐量 | speedtest |
| 延迟 | Latency | 单程传输时间 | ping |
| RTT | Round-Trip Time | 往返时延 | ping |
| 抖动 | Jitter | RTT 的波动幅度 | ping -t |
| 丢包率 | Packet Loss | 传输中丢失的包比例 | ping |
| TTFB | Time to First Byte | 首字节到达时间 | curl / DevTools |
| FCP | First Contentful Paint | 首次内容渲染时间 | Lighthouse |
| LCP | Largest Contentful Paint | 最大内容元素渲染时间 | Lighthouse |