"服务器延迟高"是最难凭感觉判断的问题之一。用户说卡,你看 CPU 和内存都很闲,带宽也没跑满,ping 一下有 200 毫秒——这时候问题才刚开头:200 毫秒是花在哪一段?是物理距离决定的下限,还是绕路绕出来的?是某一跳在丢包导致重传,还是中间路由器懒得回 ICMP 造成的假象?不同原因的处理方式完全不同,有的根本没法解决只能绕开,有的一条命令就能缓解。
这篇文章讲清楚延迟的四个来源,然后按 ping → traceroute → mtr → tcping 的顺序给出一套逐步深入的排查方法,重点讲 mtr 丢包列的正确读法(这是最多人看错的地方),最后讲跨境绕路这类特殊问题怎么定位和优化。
一、延迟由哪四部分组成
一个数据包从你的电脑到服务器再回来,时间花在四个地方。分清是哪一部分,才能知道有没有优化空间。
| 类型 | 含义 | 典型量级 | 能否优化 |
|---|---|---|---|
| 传播延迟 | 信号在光纤/铜线里传播的时间 | 由距离决定,物理下限 | 不能,只能缩短距离 |
| 传输延迟 | 把数据包推到线路上的时间(数据量 ÷ 带宽) | 小包可忽略,大包明显 | 能,加带宽或减小包 |
| 处理延迟 | 路由器查表、防火墙检查、NAT 转换、加解密 | 通常小于 1 毫秒每跳 | 有限 |
| 排队延迟 | 链路拥塞时在队列里等待 | 波动最大,可从 0 到几百毫秒 | 能,解决拥塞 |
传播延迟是硬下限。 光在光纤中的传播速度约为真空光速的三分之二,即约 20 万公里每秒(每 100 公里约 0.5 毫秒单向)。北京到洛杉矶直线距离约 1 万公里,光缆实际路径更长,单向就要 60 到 80 毫秒,往返 150 毫秒左右是物理极限。看到中美之间 150 到 180 毫秒的 RTT,那已经接近理论最优,再怎么优化线路也压不下去。
传输延迟在大包时才显著。 一个 1500 字节的包在 100 Mbps 上串行化只需 0.12 毫秒,可以忽略;但 1 MB 的数据在 1 Mbps 上需要 8 秒多,这个延迟远大于任何网络延迟。所以"小请求延迟正常、大文件特别慢"是带宽问题,不是网络质量问题。
排队延迟是波动的元凶。 链路空闲时几乎没有排队,一旦拥塞,排队时间可以快速增长到几十甚至几百毫秒。晚高峰延迟暴涨、白天正常,几乎都是排队延迟。
一个重要的推论:降低延迟最有效的手段是缩短物理距离和消除拥塞,而不是"优化服务器"。 服务器配置再高,也改变不了光缆的长度。
二、用 ping 看延迟:读法与误区
基本用法与输出解读
ping -c 20 -i 0.2 www.example.com
ping -c 100 -q www.example.com # 静默模式,只给汇总
完整输出末尾的统计行是最有价值的部分:
--- www.example.com ping statistics ---
100 packets transmitted, 97 received, 3% packet loss, time 20123ms
rtt min/avg/max/mdev = 45.123/52.678/180.445/18.234 ms
四个数字的含义和用法:
| 指标 | 含义 | 关注点 |
|---|---|---|
min |
最快的一次 | 接近链路的"空载延迟",最能反映真实网络质量 |
avg |
平均值 | 受偶发拥塞拉高,参考即可 |
max |
最慢的一次 | 偶尔很大不必惊慌,持续很大说明有排队或重传 |
mdev |
抖动(标准差) | 最容易被忽略但最重要,见下文 |
抖动比平均延迟更能反映体验。 平均 50 毫秒但 mdev 30 毫秒的链路,实际表现是忽快忽慢,对 SSH 交互、语音、实时游戏、数据库连接这类场景非常难受。一般认为 mdev 小于平均值的 10% 算稳定,超过 30% 就有明显抖动。
min 也值得单独看:如果 min 很低而 avg 很高,说明链路空载时很好、只是有拥塞;如果 min 本身就高,那是物理距离或绕路的问题,跟拥塞无关,优化方向完全不同。
常见误区:ICMP 限速不代表真实延迟
这是 ping 最大的坑。很多路由器和网络设备会对 ICMP 报文做限速(ICMP rate limiting),因为回应 ping 消耗的是设备的控制面 CPU,厂商默认限制它的速率以保护设备。
表现是:ping 显示丢包 5% 到 10%,延迟忽高忽低,但实际业务(HTTP、SSH)完全正常,速度也跑得满。
判断方法:
# 用不同间隔对比:间隔大时限速影响小
ping -c 20 -i 1.0 www.example.com # 每秒 1 个
ping -c 100 -i 0.05 www.example.com # 每秒 20 个
如果高速率下丢包率明显上升而低速率下正常,基本可以确定是 ICMP 限速,不是真实丢包。
另外几种 ping 结果误判:
ping 通不等于服务可用。 ping 走的是 ICMP,Web 服务走 TCP 80/443。服务器可以正常回应 ICMP 但 80 端口被防火墙拦掉。要测端口必须用 tcping 或 nc。
ping 不通不等于服务不可用。 很多云厂商的默认安全组拒绝 ICMP,但 80/443 是通的。这是非常常见的情况,遇到"ping 不通"先别急着下结论。
ping 的是域名还是 IP 要分清。 ping 域名时,延迟里还包含了 DNS 解析时间(但不含在 RTT 统计里)。
进阶用法
ping -M do -s 1472 www.example.com # 禁止分片,测 MTU(1472+28=1500)
ping -s 1400 www.example.com # 大包测试,暴露大包相关的问题
ping -4 www.example.com # 强制 IPv4,排除 IPv6 干扰
大包 ping 特别有用:如果小包正常、大包延迟陡增或丢包,说明链路上存在 MTU 不匹配或者某些设备对小包和大包走不同队列。
风险提示:ping -f(flood ping)会以最快速度发包,可能被视为攻击行为并影响他人网络,只在自己的内网和明确授权的链路测试中使用,不要对外部目标使用。
三、traceroute:看清路径与绕路
原理:TTL 递增
traceroute 的核心机制很简单。IP 包头里有个 TTL(生存时间)字段,每经过一台路由器减 1,减到 0 时该路由器丢弃包并返回一个 ICMP "TTL exceeded" 消息。traceroute 就利用这一点:
- 先发 TTL=1 的包,第一跳路由器返回超时消息,得到第一个 IP
- 再发 TTL=2 的包,第二跳返回,得到第二个 IP
- 依次递增,直到到达目标
Linux 上的 traceroute 默认发 UDP 包(目标端口从 33434 开始递增),Windows 的 tracert 发 ICMP 回显请求,两者原理相同但报文类型不同,这会导致结果略有差异——有些网络对 UDP 和 ICMP 的策略不一样,这也是为什么有时要两种都试。
traceroute -n www.example.com # -n 不解析域名,快很多
traceroute -T -p 443 www.example.com # 用 TCP SYN 探测,更接近真实业务
traceroute -I www.example.com # 用 ICMP 探测(类似 Windows tracert)
traceroute -w 2 -q 1 -m 20 www.example.com # 缩短超时,加快速度
TCP 模式的 -T 很实用,因为很多运营商对 ICMP 和 UDP 限速或拦截,但对 TCP 443 放行,此时用 -T 才能拿到完整路径。
输出里的三种情况
正常的行长这样,三个时间是发三个探测包的往返时间:
5 202.97.34.1 10.234 ms 10.512 ms 10.301 ms
出现星号(* * *):表示该跳设备没有在超时时间内回应。常见原因有三个:设备配置为不回应 TTL exceeded(安全策略)、回应报文在回程被丢弃、或者该跳确实拥塞。单独一跳的星号基本没有诊断价值,只要后面的跳正常就没问题。
出现多个 IP:表示这一跳有多台设备做负载均衡(ECMP),不同探测包走了不同路径。这是正常的,不代表有问题。
延迟在某跳突然跳变:比如前几跳都是 10 毫秒,第 6 跳突然变成 150 毫秒且之后一直保持高位,说明这一段是长距离链路(比如出境海缆或者跨省骨干)。这个跳变点就是地理上"出境"或"跨区"的位置,是判断绕路的关键。
单向路径的局限
traceroute 显示的是从你到目标的去程路径。回程路径可能完全不同(这叫非对称路由),而 TCP 的往返需要两条路径都好。
去程好、回程差是跨境访问极其常见的现象(常说的"去程优回程差")。要判断这个问题,必须在服务端反向 traceroute 回你的 IP,两边都测才能看清。这一点在后面讲线路时会展开。
四、MTR:把延迟和丢包定位到具体某一跳
mtr 是排查网络问题最有用的单一工具,它把 traceroute 的路径信息和 ping 的统计能力结合在一起,持续发包并给出每一跳的丢包率和延迟统计。
sudo apt install -y mtr-tiny # Debian、Ubuntu
sudo dnf install -y mtr # Rocky、RHEL、CentOS
mtr -rwc 100 -n 1.2.3.4 # 报告模式:发 100 个包后输出结果
mtr -n 1.2.3.4 # 交互模式,实时刷新
mtr -rwc 100 --tcp -P 443 www.example.com # TCP 模式,绕过 ICMP 限速
mtr -rwc 100 -u www.example.com # UDP 模式
-rwc 100 是最常用的组合:-r 报告模式、-w 宽输出(显示完整主机名)、-c 100 发 100 个包。包数不要太少,20 个包得出的丢包率统计意义很低,建议 100 起,重要场景 500 到 1000。
输出各列怎么读
Host Loss% Snt Last Avg Best Wrst StDev
1. 10.0.0.1 0.0% 100 0.4 0.5 0.3 2.1 0.2
2. 100.64.0.1 0.0% 100 1.2 1.4 1.1 5.3 0.5
3. 202.97.90.1 12.0% 100 11.2 12.8 10.9 45.1 6.2
4. 202.97.34.5 0.0% 100 12.1 13.1 11.5 38.2 5.8
5. 1.2.3.4 0.0% 100 12.5 13.4 11.8 40.1 6.0
| 列 | 含义 | 用法 |
|---|---|---|
Loss% |
该跳的丢包率 | 核心指标,但读法有讲究,见下文 |
Snt |
已发送包数 | 确认样本量足够 |
Last/Avg/Best/Wrst |
最近/平均/最好/最差延迟 | Best 反映空载质量,Wrst 反映抖动 |
StDev |
标准差(抖动) | 超过 10 毫秒说明链路不稳定 |
丢包列的三种读法(这是重点)
情况一:中间某跳丢包,但后续所有跳都不丢。 看上面例子的第 3 跳丢 12%,而第 4、5 跳都是 0%。这在物理上不可能——如果第 3 跳真的丢了 12% 的包,后面的跳必然会继承这个丢包。
结论:这是假丢包。 第 3 跳设备对 ICMP 做了限速(只回应自己需要处理的包,对转发的包不回应 TTL exceeded),或者对探测包降权处理。它不影响实际业务。这是 mtr 输出里最常见的现象,也是最多人误判的地方。
情况二:从某一跳开始,之后所有跳都持续丢包。 比如第 4 跳开始丢 5%,第 5 跳、第 6 跳也丢 5% 左右。这说明真正的丢包发生在第 3 跳到第 4 跳之间,后续跳只是"继承"了这个结果。
结论:故障点在第 3 跳和第 4 跳之间的链路上。 这是真正需要处理的问题。
情况三:只有最后一跳丢包,前面的跳都正常。 这说明丢包发生在目标服务器自己或者它前面的最后一跳。
结论:问题在服务器端。 常见原因是服务器的安全组/防火墙丢弃了部分探测包、服务器本身负载高、或者目标端的接入链路拥塞。如果丢包只在最后一跳且业务表现正常,也可能是目标端对 ICMP 限速;如果业务确实有问题,就要查服务器本身了。
简单记:看最后一跳的丢包率,那才是真实反映业务质量的数字。 中间跳的丢包要观察是否被后续继承再判断。
TCP 模式的价值
如果怀疑 ICMP 限速干扰了判断,用 TCP 模式重测:
mtr -rwc 100 --tcp -P 443 www.example.com
TCP 模式发的是 SYN 包,网络设备一般不会对它限速,结果更接近真实业务体验。ICMP 模式和 TCP 模式结果差异很大时,以 TCP 模式为准。
五、Windows 上的对应工具
# 基础连通与端口测试(Test-NetConnection 一步到位)
Test-NetConnection www.example.com -Port 443
Test-NetConnection 1.2.3.4 -Port 443 | Select-Object TcpTestSucceeded,PingReplyDetails
# DNS 解析
Resolve-DnsName www.example.com
命令行工具:
tracert -d 1.2.3.4 :: -d 不解析主机名,速度快很多
pathping -n 1.2.3.4 :: traceroute + 逐跳统计,耗时数分钟
ping -n 100 1.2.3.4
pathping 是 Windows 上被低估的工具。 它先做一次 traceroute 找出所有跳,然后对每一跳发送大量包统计丢包率,最终给出每一跳的丢包百分比。功能等价于 mtr,但更慢(通常要跑几分钟)。它的输出分两段:上半段是路径,下半段是逐跳统计,看下半段即可。
Windows 上没有内置 tcping,可以用 Test-NetConnection -Port 代替,它会给出 TcpTestSucceeded 和 RTT。需要连续测量端口延迟时,可以使用第三方的 tcping 工具,或者用 PowerShell 循环调用 Test-NetConnection。
六、tcping:测端口的真实延迟
ping 测的是 ICMP,但业务跑在 TCP 端口上。tcping 通过完成一次 TCP 握手来测量延迟,结果更接近真实体验,还能顺便确认端口是否开放。
Linux 上:
# 方法一:安装 tcping
sudo apt install -y tcping # Debian、Ubuntu
tcping -c 10 www.example.com 443
# 方法二:用 hping3 测 SYN 到 SYN-ACK 的时间
sudo apt install -y hping3
sudo hping3 -S -p 443 -c 10 www.example.com
# 方法三:用 curl 分解时间(最通用,不用装东西)
curl -o /dev/null -sS -w 'TCP连接: %{time_connect}s\nTLS握手: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n' https://www.example.com/
curl -w 的 time_connect 是到 TCP 连接建立的时间,减去 DNS 解析时间后基本等价于 tcping 的结果;time_appconnect 额外包含 TLS 握手,跨境场景下 TLS 握手要多一个往返,这也是为什么 HTTPS 站点在跨境时"首次特别慢"。
nc 也能快速验证端口:
nc -zv -w 3 www.example.com 443
读法要点:tcping 的延迟应该与 ping 的延迟接近(通常略高,因为多了内核协议栈处理)。如果 ping 是 50 毫秒而 tcping 是 500 毫秒,说明问题不在网络而在服务器——可能是连接队列满、SYN 重传、或者服务器负载过高导致响应慢。
七、跨境绕路:怎么定位,怎么优化
什么是绕路
数据包不总是走地理最短路径。运营商之间的互联、结算成本、流量工程策略,都会让流量走出人意料的路线。典型的绕路例子:从中国南方访问美国西海岸,正常应走太平洋海缆,但某条线路可能先绕到欧洲或先绕到日本再跨太平洋,延迟从 160 毫秒变成 300 毫秒以上。
定位方法
第一步:看延迟跳变发生在哪一跳。
traceroute -n -w 2 -q 1 -m 30 目标IP
找出延迟突然从几十毫秒跳到一百多毫秒的位置,那一跳就是出境点。
第二步:确认这一跳的地理位置。 把跳变点的 IP 拿到 IP 归属查询服务(如 whois 命令或公共的 IP 库网站)查一下:
whois 202.97.90.1 | grep -iE 'country|netname|descr'
curl -s ipinfo.io/202.97.90.1
如果出境点出现在预期之外的地区(比如访问美西却从欧洲出境),就是绕路。
第三步:双向都测。 在服务器上反向 traceroute 回你的 IP,看回程路径。去程和回程走不同路径(非对称路由)在跨境场景非常常见,用户感受到的是两者之和,只看一边会得出错误结论。
第四步:用 TCP 模式复核。 ICMP 可能被优先调度走好的路径,而实际业务流量走另一条。用 mtr --tcp -P 443 复核更可靠。
优化手段
| 手段 | 适用情况 | 效果 | 成本 |
|---|---|---|---|
| 换机房/就近部署 | 用户集中在某一地区 | 最彻底,直接缩短物理距离 | 中,需迁移 |
| 换更优质的线路 | 跨境、跨运营商访问 | 明显,减少绕路和拥塞 | 较高 |
| 上 CDN | 静态内容为主 | 极好,用户就近取内容 | 中 |
| 启用 BBR 拥塞控制 | 有丢包的跨境链路 | 改善吞吐,不改善延迟 | 低 |
| 多线 BGP 接入 | 国内多运营商用户 | 解决跨运营商访问 | 高 |
关于 BBR 需要说清楚:BBR 改善的是吞吐量(在有丢包的链路上更充分地利用带宽),它不能降低延迟,对传播延迟更是无能为力。看到"开了 BBR 延迟就低了"的说法要谨慎,那通常是因为吞吐改善后网页加载更快,而不是 RTT 变小了。
# 查看和启用 BBR(Linux 内核 4.9+)
sysctl net.ipv4.tcp_congestion_control
cat /proc/sys/net/ipv4/tcp_available_congestion_control
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr
echo 'net.ipv4.tcp_congestion_control = bbr' | sudo tee /etc/sysctl.d/99-bbr.conf
风险提示:修改拥塞控制算法会影响所有 TCP 连接,生产环境建议先在低峰期灰度验证,确认无异常再全量。回滚方式是把算法改回 cubic。
延迟基线参考
判断"延迟高不高"需要参照系,下面是常见场景的经验范围(RTT,实际会有所波动):
| 场景 | 正常 RTT | 说明 |
|---|---|---|
| 同机房/同可用区内网 | 0.1 ~ 1 ms | 内网互通 |
| 同城不同机房 | 1 ~ 5 ms | |
| 同省跨城 | 5 ~ 15 ms | |
| 国内跨省 | 20 ~ 50 ms | 超过 80 ms 需查路径 |
| 大陆到香港 | 30 ~ 70 ms | 视出发地和线路 |
| 大陆到日本、新加坡 | 50 ~ 120 ms | |
| 大陆到美西 | 150 ~ 220 ms | 物理下限约 150 ms |
| 大陆到欧洲 | 200 ~ 320 ms |
如果实测值大幅高于这个范围,才说明有绕路或拥塞问题需要处理;在这个范围内,基本是物理距离决定的,优化空间有限。
常见问题
ping 显示丢包 5%,但网站访问正常,要处理吗?
先按第四节的方法判断丢包发生在哪一跳。如果只有中间跳丢包、最后一跳不丢,那是 ICMP 限速造成的假象,不用处理。确认方法是用 mtr --tcp -P 443 复核,TCP 模式下最后一跳正常就说明业务不受影响。
mtr 中间几跳全是星号,后面又正常,是有问题吗?
不是。星号只说明该跳设备不回应探测包(安全策略很常见),只要后面的跳能到达目标且延迟正常,路径就是通的。真正需要关注的是"从某跳开始后续全部丢包"和"最后一跳丢包"这两种模式。
延迟忽高忽低是什么原因?
看 mdev 或 mtr 的 StDev 列。抖动大通常是排队延迟造成的,即链路存在周期性拥塞。可用 ping -c 500 -q 在不同时段测几轮,如果晚高峰抖动明显更大,就是拥塞,需要换线路或加带宽;如果全天抖动都大,可能是无线接入或链路质量问题。
为什么 ping 很快但打开网页很慢?
ping 测的是小包 ICMP 的往返,网页加载还要加上 DNS 解析、TCP 握手、TLS 握手、服务端处理、以及内容传输。用 curl -w 把各阶段时间打出来,就能看出慢在哪一段。跨境 HTTPS 站点首次访问多出的 TLS 握手往返,经常是几百毫秒的来源。
服务器 ping 不通,但 SSH 能用,正常吗?
正常。ping 走 ICMP,SSH 走 TCP 22,很多安全组默认只放行 TCP 端口而拒绝 ICMP。这说明配置反而是合理的(减少了暴露面)。要确认网络连通性,用 nc -zv IP 端口 或 Test-NetConnection -Port 测具体端口更准确。
换线路能降低延迟吗?
能,但有上限。换线路可以减少绕路和拥塞排队,把 300 毫秒降到 180 毫秒是可能的;但传播延迟改不了,中美之间 150 毫秒左右是物理下限。如果实测值已经接近理论下限,唯一有效的办法是把服务部署到离用户更近的地方(就近部署或 CDN)。
总结
- 延迟由传播、传输、处理、排队四部分组成:传播延迟由距离决定无法优化(光纤中约每 100 公里 0.5 毫秒单向),排队延迟是波动的元凶,晚高峰变慢基本都是它。
- ping 要重点看
min和mdev:min 接近空载质量,mdev 是抖动,超过平均值 30% 就会明显影响交互体验;ICMP 限速会造成假丢包,用不同发包间隔对比可识别。 - traceroute 靠 TTL 递增工作,星号不等于故障(只是设备不回应),延迟突然跳变的那一跳通常就是出境点;它只显示去程路径,回程可能完全不同,跨境问题必须双向都测。
- mtr 丢包列的正确读法是:中间跳丢包但后续不丢 = 假丢包(限速),从某跳开始后续全部继承丢包 = 真实故障点在该跳之前,只有最后一跳丢 = 问题在服务器端。最后一跳的丢包率才是真实业务质量的反映。
- tcping(
mtr --tcp -P 443、hping3 -S、curl -w的time_connect)测的是端口级延迟,更接近真实体验;ping 快而 tcping 慢说明问题在服务器不在网络。 - 跨境绕路用"延迟跳变点 + IP 归属查询 + 双向测试"定位,优化优先级是就近部署和 CDN 优于换线路优于调参;BBR 只能改善吞吐、不能降低延迟,改之前要有回滚方案。
企业QQ咨询




