# 别再ping着发呆了:银行老运维的10分钟网络排障法
> **云间豹变 | Linux调优实战系列** --- 记得某次半夜值班遇到告警,应用电话打过来:「A系统调B系统接口,间歇超时,帮忙看一下网络。」 我揉了揉眼睛,`ping 10.10.1.20`——通。 `telnet 10.10.1.20 8080`——通。 「网络没问题啊,你们应用层自己查。」 挂了电话,五分钟后告警又来了,一晚上反复如此,第二天还被喷没解决问题。 **这是我早年入行踩过最深的坑:ping通,不等于网络没问题。** 后来我整理了一套「10分钟网络定位法」,从那以后再也没被这类网络基础问题「骚扰」过。 --- ## 先建一张「网络排查地图」 从技术原理角度来看,银行生产环境的网络问题,藏在至少6个层面。出了事你得知道先查哪层:
排查层面
工具
能看到什么
连通性
`ping / `ping6``
基础ICMP可达性
路由
`ip route / `traceroute``
包走的路径,在哪一跳丢的
端口
`ss / `netstat``
本地监听和连接状态
DNS
`dig / `nslookup``
域名解析对不对
网卡物理层
`ethtool / `ip addr``
网卡UP、协商速率、有无错包
抓包
`tcpdump`
包到底有没有到本机,TCP握手细节
应用层
`curl -w`
请求慢在哪一段(DNS/TCP/SSL/服务端)
**10分钟排障法则的核心**:不要上来就ping。先问清楚症状(慢?不通?间歇?),再从底层往上层逐层查。 --- ## 六个命令,覆盖物理层到应用层 **① ss — 连接状态一看就懂** ``` # 查看所有TCP连接,按状态分组统计 # NR>1 跳过表头行,避免把 "State" 也算进去 ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn # 查看哪个进程在监听8080端口(排障必用) sudo ss -tlnp | grep 8080 # 查看已建立的连接,按本地端口聚合,看有没有异常外联 # state established 比简写 est 兼容性更好(老版本 RHEL/CentOS 适用) ss -tn state established | awk 'NR>1 {print $4}' | sort | uniq -c | sort -rn | head -20 ``` **② ip route — 路由表是第一现场** ``` # 查看路由表,默认路由指向谁 ip route show # 追踪到目标IP的路径(每一跳延迟,IP都是随便取的,无需在意) traceroute -n 10.10.1.20 # 或者用mtr(实时刷新,推荐) mtr -r -c 10 10.10.1.20 ``` **③ tcpdump — 抓包,看清包到底到没到** ``` # 抓取到达eth0的HTTP流量(排障神器) sudo tcpdump -i eth0 -nn port 80 and host 10.10.1.20 -c 100 # 抓取ICMP包,看ping的包有没有出去 sudo tcpdump -i eth0 -nn icmp # 保存到文件,事后用Wireshark分析 sudo tcpdump -i eth0 -w /tmp/capture.pcap port not 22 ``` **④ dig — DNS问题别再背锅了** ``` # 查A记录,看解析对不对 dig +short api.example.com # 追踪DNS解析全过程(看是哪一层DNS的问题) dig +trace api.example.com # 反向解析,从IP查域名(安全审计常用) dig -x 10.10.1.20 ``` **⑤ ethtool — 网卡物理层排障** ``` # 看网卡是否UP、协商速率和双工模式(百兆/千兆/万兆) ethtool eth0 | grep -E "Speed|Duplex|Link detected" # 看网卡驱动信息和固件版本 ethtool -i eth0 # 看网卡收发包统计(有多少错误、丢包) ethtool -S eth0 | grep -iE "drop|error|discard" ``` > 💡 **什么时候用 ethtool?** 当你怀疑是"网线松了""网卡掉速""协商到百兆而不是千兆"这类物理层问题的时候。`ping` 看不出来,`ss` 也看不出来,只有 `ethtool` 能确认。 --- **⑥ curl — 应用层时间拆解(从开发角度排查必备)** ``` # 把一次HTTP请求的时间拆成 DNS→TCP握手→SSL→服务端处理 四段 curl -w '\nDNS解析: %{time_namelookup}s TCP握手: %{time_connect}s SSL握手: %{time_appconnect}s 服务端首字节: %{time_starttransfer}s 总耗时:    %{time_total}s\n' \      -o /dev/null -s http://10.10.1.20:8080/api/health ``` > 💡 `ping` 告诉你网络通不通,`curl -w` 告诉你**慢在哪一段**。DNS 慢找 DNS,TCP 握手慢找路由,服务端慢找应用——不用猜。 --- ## 真实案例:10分钟从「ping通」找到「MTU丢包」 这是我处理过最「烧脑」的一次故障。 **故障现象**:应用A调用应用B的接口,小请求正常(GET /health 秒回),但带 payload 的 POST 大请求就超时。A和B在同一网段,`ping` 正常,`telnet` 端口也通。 **定位过程(实际耗时10分钟)** ``` # 第1分钟:确认基础连通性 ping 10.10.1.20 # 通。不是网络不通的问题。 # 第2分钟:用curl模拟大请求——复现问题 curl -X POST -d "$(dd if=/dev/urandom bs=1000 count=50 2>/dev/null | base64)" \      --connect-timeout 3 --max-time 10 \      http://10.10.1.20:8080/api/submit # 超时!小请求OK,带body的大请求挂。 # 第3分钟:检查TCP握手时的MSS协商(tcpdump抓包) sudo tcpdump -i eth0 -nn 'tcp port 8080 and (tcp[tcpflags] & tcp-syn != 0)' -c 3 # 看到 A→B SYN 包中 MSS=1460(A端MTU 1500 正常) # 看到 B→A SYN-ACK 包中 MSS=8960(B端MTU 9000 巨帧!) ``` **问题就在 MSS=8960** B 端虚拟机迁移后网卡被配成了 MTU=9000。TCP 握手时,B 向 A 通告 "我能收 8960 字节的 TCP 段"。A 端客户端看到这个值,尝试构造接近 8960 字节的大段发送——但 A 自己的网卡 MTU 只有 1500,内核只能做 **IP 分片** ``` # 第4分钟:验证分片行为 ip link show eth0 | grep mtu # A端: mtu 1500 ip link show eth0 | grep mtu  # 在B端执行 # B端: mtu 9000  ← 问题在这 ``` 被分片的 IP 包经过交换机时,部分交换机对分片包的处理不稳定——重组队列有限、分片可能乱序到达。**一旦有一个分片丢了,B 端的 TCP 层就永远等不到完整段,应用层超时。** 小请求为什么没事?因为小于 1460 字节,根本不需要分片。 ``` # 第5分钟:临时修复——把B端MTU改回1500,立即恢复 sudo ip link set eth0 mtu 1500 # 验证:再次curl大请求 curl -X POST -d "$(dd if=/dev/urandom bs=1000 count=50 2>/dev/null | base64)" \      --connect-timeout 3 --max-time 10 \      http://10.10.1.20:8080/api/submit # 正常返回! ``` **永久生效**(根据是否使用 NetworkManager 选一种,切记提工单去做): ``` # 方式一:传统 network-scripts(RHEL 7 及以前) sed -i 's/^MTU=.*/MTU=1500/' /etc/sysconfig/network-scripts/ifcfg-eth0 # 方式二:NetworkManager(RHEL 8+ 及大部分现代发行版) nmcli con mod eth0 802-3-ethernet.mtu 1500 nmcli con up eth0 ``` 从告警到恢复,**10分钟搞定手工** 如果用传统方式——先找应用组查代码、再找网络组查路由、再逐层拉会——这个故障保底耗2小时。 --- ## 放进crontab的网络巡检脚本 不要等出事才查。这个脚本每天跑一次,主动发现问题: ``` #!/bin/bash # network_check.sh — 日常网络健康巡检 REPORT="/tmp/network_report_$(date +%Y%m%d).txt" echo"=== 网络巡检报告 $(date) ===" > "$REPORT" # 1. 检查默认路由是否存在 DEFAULT_ROUTE=$(ip route | grep default | wc -l) echo"默认路由数量: ${DEFAULT_ROUTE}" >> "$REPORT" [ "$DEFAULT_ROUTE" -eq 0 ] && echo"[WARN] 缺少默认路由!" >> "$REPORT" # 2. 检查DNS配置是否正常(银行环境不通外网,改查本地resolver) DNS_NS=$(grep -c '^nameserver' /etc/resolv.conf 2>/dev/null) echo"DNS服务器数量: ${DNS_NS}" >> "$REPORT" [ "$DNS_NS" -eq 0 ] && echo"[WARN] 未配置DNS服务器!" >> "$REPORT" # 能访问外网的机器可以加一步验证:dig +time=2 +short 你的内网域名 # 3. 检查网卡状态和协商速率 for iface in $(ls /sys/class/net/ | grep -v lo); do     STATE=$(cat /sys/class/net/$iface/operstate 2>/dev/null || echo"N/A")     SPEED=$(ethtool $iface 2>/dev/null | grep -oP 'Speed: \K.*')     [ -z "$SPEED" ] && SPEED="N/A"     echo"网卡 $iface: 速率=${SPEED} 状态=${STATE}" >> "$REPORT"     [ "$STATE" != "up" ] && echo"[WARN] 网卡 $iface 不是UP状态!" >> "$REPORT" done # 4. 检查MTU是否与标准值一致(巨帧未关是常见坑) for iface in $(ls /sys/class/net/ | grep -v lo); do     MTU=$(cat /sys/class/net/$iface/mtu 2>/dev/null)     [ -n "$MTU" ] && [ "$MTU" -ne 1500 ] && \         echo"[WARN] 网卡 $iface MTU=${MTU} (非标准1500)!" >> "$REPORT" done # 5. 检查异常连接数(根据业务实际情况调整阈值) ESTAB_COUNT=$(ss -tn state established | tail -n +2 | wc -l) echo"当前ESTABLISHED连接数: ${ESTAB_COUNT}" >> "$REPORT" [ "$ESTAB_COUNT" -gt 500 ] && echo"[WARN] 连接数超阈值(${ESTAB_COUNT}),请核查" >> "$REPORT" # 6. 检查有没有丢包的网卡 for iface in $(ls /sys/class/net/ | grep -v lo); do     RX_DROP=$(cat /sys/class/net/$iface/statistics/rx_dropped 2>/dev/null || echo 0)     TX_DROP=$(cat /sys/class/net/$iface/statistics/tx_dropped 2>/dev/null || echo 0)     [ "$RX_DROP" -gt 100 ] && echo"[WARN] $iface RX丢包: $RX_DROP" >> "$REPORT"     [ "$TX_DROP" -gt 100 ] && echo"[WARN] $iface TX丢包: $TX_DROP" >> "$REPORT" done cat "$REPORT" ``` 和之前排查日志一样[别再tail -f发呆了:银行老运维的10分钟日志排障法](https://mp.weixin.qq.com/s?__biz=MzkwMzI3ODA4Mg==&mid=2247483873&idx=1&sn=8ac51fd8341e0ef1b151a8e2a9939cce&scene=21#wechat_redirect),加进crontab每天早上8点跑一次: ``` 0 8 * * * /opt/scripts/network_check.sh >> /var/log/network_daily.log 2>&1 ``` --- **尾声** 10分钟定位,不是玄学,是方法。 地图建好了,从底层往上层逐层推——物理网卡→路由→传输层→应用端口,基本不会走弯路。 下次碰到网络故障,不用只会ping了。 --- **你遇到过最「烧脑」的网络故障是什么?** 是MTU不匹配,还是路由表被误改? 评论区聊聊,没准能帮到下一个正在ping着发呆的人。 --- *👉 觉得有用就转发给你的运维bro,在网络排障的时候说不定用得上* *如果不想错过下一期排障实战,点个关注,每次更新直接推到你微信里。顺手点个「在看」,让我知道这类干货你们爱看。*