一次跨网延迟飙到300ms的排查全过程

摘要:客户反馈服务器访问慢,ping延迟从正常5ms飙到300ms。服务器面板全是绿的,机房说网络没问题。最后怎么定位到根因的?完整复盘一次跨网延迟排查,从现象到定位到解决,每一步都有命令和输出。

关键词:跨网延迟、网络排查、traceroute、mtr、BGP、互联节点

分类:网络运维 / IDC / 故障排查


故障现象

周三下午三点,一个做电商的客户找过来:

“你们服务器是不是有问题?管理后台之前秒开的,现在要等好几秒。”

我第一反应是登上去看看。

ssh root@服务器IP

秒连,不觉得慢。

top -bn1 | head -5
top - 15:02:31 up 186 days,  4:23,  1 user,  load average: 0.35, 0.28, 0.22
%Cpu(s):  4.2 us,  1.3 sy,  0.0 ni, 93.8 id,  0.5 wa,  0.0 hi,  0.2 si
MiB Mem :  32000.0 total,  18500.0 free,   8200.0 used

CPU 4%,内存够,负载0.35。完全正常。

curl -s -o /dev/null -w "%{time_total}" http://localhost/
# 0.018

本机访问18ms,正常。

服务器没问题。那问题出在哪?


从用户视角去测

以前做开发的时候,查到"服务器正常"就停了,然后跟运维扯皮说"我这边没问题"。

做了IDC之后学到一件事:你自己SSH上去觉得快没用,要从用户的网络去测。

让客户在浏览器打开ping.pe,输入服务器IP。30秒出来的结果:

北京联通:  287ms  丢包12%
北京电信:  8ms    丢包0%
上海联通:  312ms  丢包15%
上海电信:  6ms    丢包0%
广州移动:  180ms  丢包8%
广州电信:  5ms    丢包0%
成都联通:  320ms  丢包18%

规律很明显:电信正常,联通和移动全炸了。

这台服务器是电信单线机房,联通用户访问要跨网,这个我知道。但之前联通用户也就50-80ms,从来没到过300ms。一定是中间有什么变了。


traceroute看路径

从我自己的联通线路服务器traceroute过去:

traceroute -n 电信服务器IP
 1  10.x.x.1         0.5ms
 2  112.x.x.1        2.1ms
 3  219.x.x.1        8.3ms
 4  219.x.x.1       15.6ms
 5  * * *
 6  202.97.x.x     245.2ms    ← 这一跳炸了
 7  202.97.x.x     268.3ms
 8  61.x.x.1       280.5ms
 9  服务器IP        295.8ms

同样的路径,之前第6跳大概70ms,现在飙到了245ms。

202.97.x.x 是电信163骨干网的互联节点IP段。从联通跨到电信的那一跳,延迟突然增大了。

但traceroute只跑了一次,结果不一定准。中间设备可能限速ICMP导致显示的延迟不准。需要用mtr多发几个包确认。


mtr确认

mtr -n -c 200 -r 电信服务器IP
Host                Loss%  Snt   Last  Avg   Best  Wrst  StDev
1. 10.x.x.1         0.0%  200   0.3   0.4   0.2   0.9   0.1
2. 112.x.x.1        0.0%  200   2.1   2.3   1.8   4.5   0.4
3. 219.x.x.1        0.0%  200   8.3   9.1   7.5  15.2   1.5
4. 219.x.x.1        0.0%  200  15.6  16.3  14.0  25.1   2.1
5. 202.97.x.x      12.0%  200  245.3 238.7 210.0 312.5  25.3
6. 202.97.x.x      11.5%  200  250.1 242.3 215.0 320.0  24.8
7. 61.x.x.1         8.0%  200  260.5 255.1 230.0 335.0  22.1
8. 服务器IP          8.0%  200  258.2 250.3 225.0 330.0  21.5

第5跳开始Loss%从0%跳到12%,延迟从16ms飙到245ms,StDev=25ms抖动很大。

而且从第5跳开始,后续每一跳都保持高延迟和高丢包。这说明问题就在第5跳,不是后面的设备恢复了前面只是ICMP限速。

第5跳 202.97.x.x 是电信骨干网地址。问题出在电信和联通的互联节点。

有个判断技巧:如果某一跳Loss%高但后面恢复正常,通常是那跳设备限速ICMP,不影响实际业务流量。但如果Loss%从某一跳开始一直持续到目标,那就是真丢包。 这次属于后者。


交叉验证

为了排除"只是我这条路径有问题",从几个不同方向测了一下:

# 从另一台南方电信服务器traceroute到联通测试IP
traceroute -n 联通测试IP
 5  202.97.x.x      12.3ms
 6  202.97.x.x     248.5ms    ← 同样在这里卡住
 7  219.x.x.x      255.2ms

不同城市、不同电信出口,都在同一个互联节点区域出现高延迟。

搜了一下"电信联通互联 故障"——果然,当天下午已经有人在论坛上反馈跨网访问异常。

联系机房确认,收到了运营商通知:电信联通之间的某个互联节点在做扩容割接,预计影响4-6小时。

根因确认了。不是我们的问题,不是机房的问题,是运营商互联节点的割接导致跨网流量绕路,延迟飙升。


临时应急

客户等不了6小时。下午是电商运营的操作高峰期,后台慢了直接影响干活。

几个方案快速过了一遍:

CDN? 适合静态资源,但客户的后台大量动态API请求,CDN帮不了太多。而且现在临时上CDN,配置、域名切换、缓存预热,来不及。

HTTPDNS? 适合APP端,但客户的后台是Web端浏览器访问,浏览器的DNS不太好控制。

临时加联通线路? 跟机房协调临时分配一个联通IP,联通用户直接走联通线路进来,不经过互联节点。

选了第三个方案,最快能落地。

跟机房沟通大概一个小时,临时分配了一个联通IP。

# 添加联通IP
ip addr add 联通IP/24 dev eth1
# Nginx额外监听联通IP
server {
    listen 联通IP:80;
    server_name admin.example.com;
    # ...其他配置不变
}

DNS那边做分运营商解析:

admin.example.com
  → 电信用户解析到电信IP
  → 联通用户解析到联通IP

联通用户延迟从300ms降回了15ms。

这个方案不完美——移动用户还是慢,而且管理两套IP增加了运维复杂度。但作为应急够用了。


后续优化

互联节点割接第二天凌晨恢复了,跨网延迟回到了正常的50-80ms。

但这次之后客户开始认真考虑长期方案了。总不能每次运营商割接就临时加线路。

第一步:上CDN

静态资源全部走CDN。后台的JS、CSS、图片、字体不再从源站拉。

location ~* \.(js|css|png|jpg|gif|ico|woff2)$ {
    expires 7d;
    add_header Cache-Control "public, immutable";
}

光这一步就减轻了源站60%以上的请求量。CDN节点覆盖各运营商,联通用户访问CDN是同网的,不受跨网影响。

第二步:APP端HTTPDNS

客户有一个配套的APP端。APP端可以控制DNS解析,用HTTPDNS绕过LocalDNS,直接获取同网最优的服务器IP。

String ip = HttpDns.getIpByHost("api.example.com");
URL url = new URL("http://" + ip + "/api/request");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("Host", "api.example.com");

Web端暂时没有好的HTTPDNS方案,靠CDN覆盖。

第三步:要不要换BGP?

客户问我这个问题。我帮他分析了一下:

他的用户80%是电信用户(南方电商),联通约15%,移动约5%。

换BGP三线,带宽成本增加60-80%。但80%的用户本来就是电信,跨网问题只影响20%的用户。

最终决定不换BGP。保持电信单线 + CDN + HTTPDNS,成本增加不多,但覆盖了大部分跨网场景。

如果他是面向全国的业务、各运营商用户分布均匀,那BGP多线是必须的。具体情况具体分析,不是"有跨网问题就一定要换BGP"。


几点感受

服务器正常不代表没问题。 这次从头到尾服务器面板全是绿的。如果只看服务器监控,结论是"一切正常"。但用户就是觉得慢。排查"用户说慢"的问题,必须从用户的网络去测,不能只看自己这端。

ping.pe真的很好用。 一个网页输入IP,30秒出全国几十个节点的延迟和丢包数据。做IDC之后这个工具几乎每天都在用。开发的同学排查跨网问题的时候也可以用,比找不同地方的朋友帮忙ping方便多了。

traceroute一次不够,要跑mtr。 traceroute只发3个包,结果可能有偶然性。mtr发几百个包做统计,数据可靠得多。特别是判断某一跳的丢包是真丢包还是ICMP限速,mtr的Loss%持续性比traceroute的一次性结果有说服力。

应急方案要提前想好。 这次临时加联通线路花了一个多小时。如果提前有CDN和HTTPDNS,用户可能根本感知不到这次故障。面向公网的服务,CDN应该作为标配,不是出了问题才去搞。


排查时间线

15:00  客户反馈慢
15:02  SSH登服务器查状态,CPU/内存/负载正常
15:05  本机curl测试18ms,正常
15:08  让客户用ping.pe测,发现联通延迟300ms+
15:15  traceroute看路径,定位到互联节点
15:25  mtr持续追踪,确认丢包12%且持续到目标
15:30  从不同方向交叉验证,确认是区域性问题
15:35  搜到运营商故障通告,确认是互联节点割接
15:50  跟机房协调临时加联通线路
16:30  线路配好,联通延迟恢复到15ms
16:40  客户确认正常

排查定位花了35分钟,协调和实施花了50分钟。如果提前有CDN方案,整个过程可能15分钟就解决了——用户走CDN不受影响,我们只需要在后台静静等运营商恢复。


这个案例挺典型的。服务器没问题、机房没问题、运营商也没"出故障"(割接是计划内的),但用户体验就是差了。跨网问题就是这样,每一方都觉得自己没问题,但用户体验是实实在在变差了。

面向全国用户的业务,CDN和HTTPDNS建议作为标配提前做好。出了问题再搞,用户已经跑了。

有问题评论区聊。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐