丢包和重传为什么会严重影响网络性能?如何定位和优化?
简化版
丢包会让 TCP 等待重传、降低拥塞窗口,导致延迟升高和吞吐下降;对实时音视频还会造成卡顿、花屏和抖动。定位时要看 ping/mtr、tcpdump、重传率、网卡错误、队列丢弃、链路拥塞和服务端负载。优化方向包括减少拥塞、修复物理链路、调整缓冲和队列、使用 CDN 或就近接入,以及对实时业务采用 FEC、降码率或 QUIC。
详细版
丢包影响性能有两条路径:
| 路径 | 影响 |
|---|---|
| 重传等待 | 包没到,需要重新发送,响应时间变长 |
| 拥塞控制 | TCP 认为网络拥塞,降低发送窗口,吞吐下降 |
例如 RTT 50 ms 时,一次快速重传可能额外增加几十毫秒;如果等到 RTO 超时,可能增加 200 ms、1 秒甚至更久。少量丢包对大文件下载也很致命,因为 TCP 会收缩拥塞窗口,链路带宽无法跑满。
排查不能只看“ping 通不通”。要看丢包发生在哪一跳、是否伴随重传、是否只有高峰期出现、网卡是否有 error/drop、交换机端口是否有 CRC 错误、应用是否因为发送缓冲满而丢弃。
完整版教学
一、丢包为什么不只是“少了一个包”
网络协议不是每个包都孤立存在。一个 TCP 字节流被拆成多个段,只要中间某段丢了,接收端后面的数据即使到了,也可能因为缺口无法按序交给应用。发送端要发现丢包、重传缺失段,接收端才能继续交付。
发送: 1 2 3 4 5
接收: 1 2 _ 4 5
应用: 只能按序拿到 1 2,等待 3 重传
这就是丢包放大延迟的原因。对请求响应来说,一个关键包丢失可能拖慢整个请求;对长连接来说,丢包还可能造成后续数据排队等待。
二、TCP 如何发现丢包
TCP 主要通过重复 ACK 和超时发现丢包。接收端发现中间缺了一个段,会持续 ACK 已连续收到的位置。发送端收到多个重复 ACK,可以推断某个段丢了,触发快速重传。如果没有足够重复 ACK,只能等重传超时 RTO。
发送端发: seq=1,2,3,4,5
接收端缺 3,收到 4/5 后仍 ACK=3
发送端收到多个 ACK=3 -> 快速重传 seq=3
快速重传通常比 RTO 快很多。RTO 是保守机制,可能从几百毫秒开始,网络差时指数退避增长。面试里要能说出“重复 ACK 快速重传”和“RTO 超时重传”的区别。
重传最怕等 RTO,因为那不是多发一个包这么简单,而是整个连接进入保守等待。
三、丢包会触发拥塞窗口下降
TCP 把丢包视为网络拥塞信号之一。传统拥塞控制如 Reno/CUBIC 遇到丢包会降低拥塞窗口,减少发送速率。这样做保护网络,但也会让吞吐下降,尤其是高带宽高延迟链路。
假设拥塞窗口能支撑 100 Mbps,遇到丢包后窗口减半,吞吐可能掉到 50 Mbps,再慢慢爬升。如果链路持续有随机丢包,窗口不断被打断,就很难跑满带宽。
吞吐曲线:
升高 -> 丢包 -> 降窗 -> 再升高 -> 再丢包 -> 再降窗
这也是为什么 1% 丢包看起来很小,却可能让 TCP 下载速度下降明显。
四、丢包位置决定优化方向
丢包可能发生在客户端 Wi-Fi、运营商链路、企业网关、负载均衡、服务端网卡、内核队列或应用层。不同位置的解决方式完全不同。只知道“有丢包”还不够,要定位在哪里丢。
| 位置 | 现象 | 排查线索 |
|---|---|---|
| Wi-Fi | 抖动大,移动后变化 | 信号强度、重试率 |
| 物理链路 | CRC/error 增长 | 交换机端口计数器 |
| 拥塞队列 | 高峰期 drop | 队列长度、带宽利用率 |
| 服务端内核 | softnet drop | netstat -s、网卡队列 |
| 应用处理慢 | 接收缓冲满 | CPU、GC、线程池 |
如果只有某个地域慢,优先怀疑跨网链路和路由;如果所有地域高峰期慢,优先看服务端容量和出口带宽。
五、如何用工具判断丢包和重传
ping 可以粗看 RTT 和丢包,但 ICMP 可能被限速,不一定代表业务 TCP。mtr 能持续观察每一跳的延迟和丢包,但中间路由器也可能只限制 ICMP 回复。抓包能直接看到 TCP Retransmission、Duplicate ACK、Out-of-Order。
ping -c 100 example.com
mtr -rw example.com
tcpdump -i eth0 host 10.0.0.5 and tcp
判断重传时更应该看端到端业务流量,而不是只看中间节点。中间某跳显示 80% 丢包,但后续跳没有丢,通常说明该路由器限制 ICMP 回复,不代表转发真丢。
六、实时业务和 TCP 业务的优化不同
文件下载、API 请求一般用 TCP,丢包后可靠重传是必须的。实时音视频更看重低延迟,过期的包即使重传回来也没意义,所以常使用 RTP/UDP、FEC、NACK、码率自适应等机制。
| 业务 | 丢包处理倾向 |
|---|---|
| 文件下载 | 必须重传,保证完整 |
| API 请求 | 重传保证可靠,关注尾延迟 |
| 音视频 | 部分恢复,优先实时 |
| 游戏同步 | 关键状态可靠,频繁位置可丢 |
这也是 QUIC 有价值的原因之一:它基于 UDP 实现可靠传输,并把多路流的队头阻塞控制在单个流内,丢包影响范围比 TCP 上的 HTTP/2 更小。
七、优化要先分清随机丢包和拥塞丢包
随机丢包可能来自无线干扰、物理层错误、设备问题;拥塞丢包来自队列满、带宽不够或突发流量。随机丢包要修链路,拥塞丢包要控流量、扩容、调队列和拥塞控制。
随机丢包: error/CRC 增长、和流量峰值关系弱
拥塞丢包: 高峰期明显、队列满、带宽接近上限
常见优化包括:修复网线/光模块、调整 MTU、开启合适的队列管理、使用 CDN 就近接入、限速削峰、优化重试风暴、调整 TCP 拥塞控制算法和缓冲区。
八、常见误区与追问
- 误区:ping 没丢包就说明业务不丢包。 ICMP 和业务 TCP 路径、限速策略、包大小可能不同。
- 误区:中间某跳 mtr 丢包就一定是那里故障。 如果后续跳不丢,通常只是该节点限制 ICMP 回复。
- 误区:丢包只会影响延迟,不影响吞吐。 TCP 会降拥塞窗口,吞吐也会明显下降。
- 误区:重传越多说明 TCP 越可靠,所以没关系。 重传是补救,不是免费能力,会增加延迟并降低有效吞吐。
- 追问:快速重传和 RTO 有什么区别? 快速重传由重复 ACK 触发,RTO 是超时后触发,后者通常代价更高。
- 追问:如何判断物理链路问题? 看网卡 error/drop、交换机 CRC、光模块告警、双工速率协商和链路日志。
- 追问:实时音视频为什么不完全依赖 TCP 重传? 过期媒体帧重传回来也没用,实时业务更重视低延迟和可接受降质。
九、加强记忆
丢包影响性能有两把刀:一把是重传等待拉高延迟,一把是拥塞控制降窗降低吞吐。排查时按端到端工具、抓包、设备计数器、服务端队列逐层定位;优化时先判断随机丢包还是拥塞丢包,再决定修链路、扩容、控流、调队列或换协议策略。