告警群里有人贴一句:“我 ping 了,通,28ms,不是网络问题。”
然后用户工单还在刷“打不开”。
ping 检测最容易被用成“甩锅工具”,而不是“定位工具”。
原因很直接:ICMP 只是网络层控制报文,云上环境默认可能不回;Ping 通只证明“IP 可达”,不证明端口开着、TLS 握得上、业务返 200。
把 ping 检测用对,得把它放进一个漏斗:
ICMP 可达 → 端口可达 → 应用可达 → 多节点一致
本文讲一套可落地的 ping 检测工程化方法:单点为什么不可信、ICMP 禁回怎么补刀、多节点基线怎么建、告警怎么降噪、和 TCPing/HTTP 怎么串成自动定责。
一、先给 ping 检测定边界
ping 实际只看三件事:
- 通不通:ICMP Echo 有没有回
- 延迟:RTT 均值和抖动
- 丢包:连续样本里的丢失比例
它证伪能力强,证明能力弱:
- 不通 → 网络层一定有问题(或 ICMP 被吃)
- 通 → 只能说明“IP 层勉强能到”,后面端口/证书/业务全都不知道
云环境常见“假阴性”:
- 安全组没放 ICMP
- 防火墙只回 80/443,丢 Echo
- 高防/CDN 边缘替源站回 ping
- 容器网络、Anycast 节点对 ICMP 限流
所以生产里 ping 检测的第一条铁律:
Ping 不通先别重启,Ping 通了也别下班。
二、连通性漏斗:四层收口
text
L3 ICMP ping → 网络层可达 L4 TCP nc/tcping → 端口真监听 L5 TLS openssl/curl → 证书/握手没问题 L7 HTTP curl -I → 业务真返回
排障顺序从下往上,哪层断在哪层收口。
层 |
工具 |
通了说明 |
不通常见原因 |
L3 |
ping |
路由可达(可能假象) |
ICMP 禁回/线路断/主机宕 |
L4 |
nc -zv |
端口在监听 |
安全组/防火墙/服务没起 |
L5 |
curl -v |
TLS 协商成 |
证书过期/链不完整/TLS 版本错 |
L7 |
curl -I |
业务返状态码 |
后端 5xx/网关超时/回源错 |
典型组合判读:
- ping 通 + 443 不通 → 安全组或本地防火墙拦了 TCP
- ping 不通 + 443 通 → ICMP 被禁,服务活着
- 443 通 + HTTP 超时 → 应用层假死/连接池满
- 多节点有的通有的不通 → 调度/运营商/边缘节点问题
三、单点 ping 为什么不能当结论
本地执行:
bash
ping example.com
样本 = 你这台机器 + 你这家 ISP + 这一秒网络状态。
用户可能在:
- 广东移动
- 宁夏联通
- 校园教育网
- 日本家庭宽带
“我这边通”在工单里没有说服力。
正确做法:同时间窗多节点 ping 检测
- 电信 / 联通 / 移动 / 教育网
- 华北 / 华南 / 海外
- ICMP 和 TCPing 443 一起跑
输出对照:
text
电信 上海 ping 26ms 丢包0% 443 通 联通 北京 ping 41ms 丢包2% 443 通 移动 广东 ping 88ms 丢包12% 443 通 海外 法兰 ping 180ms 丢包0% 443 通
结论立刻变成:
不是服务器挂,是广东移动出口丢包,CDN 调度没避开劣化链路。
四、ICMP 被禁时的补刀三连
云主机默认策略常这样:
bash
# 1. ICMP 层 ping 120.55.xx.xx # 可能全丢 # 2. 端口层 nc -zv 120.55.xx.xx 443 # 看 TCP 握手 # 3. 应用层 curl -sv --connect-timeout 5 https://example.com
端口通、curl 返 200 → 服务完全正常,只是 ICMP 被丢。
Linux 临时开 ICMP(排障用):
bash
sysctl -w net.ipv4.icmp_echo_ignore_all=0
生产别长期全开,按需要放类型。
五、把 ping 检测做成基线,而不是单次触发
单次 ping 是噪声,长期基线是信号。
1. 建基线
对核心域名/IP 存:
- 各节点历史 RTT p50/p95
- 丢包率日基线
- 跳数/TTL 分布
2. 告警用“偏离”不用“阈值”
别写“RTT>100ms 告警”(跨洋本来就高)。
写:
- 同节点 RTT 超自身基线 2σ
- 丢包率连续 3 周期 >3%
- 多节点里某运营商集体红
3. 自动三连探测
探针脚本:
bash
check() { ping -c 5 $IP >/dev/null 2>&1 && icmp=ok || icmp=fail nc -zv $IP 443 >/dev/null 2>&1 && port=ok || port=fail code=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 https://$DOMAIN) echo "icmp=$icmp port=$port http=$code" }
输出直接进告警卡片:
icmp=fail port=ok http=200→ 只标“ICMP 禁回”,不派网络工单icmp=ok port=fail http=-→ 派安全组/防火墙工单icmp=ok port=ok http=502→ 派后端工单
降噪效果:把“打不开”从 1 类报警拆成 3 类派单。
六、mtr:ping 检测看不出“哪一跳”时补刀
bash
mtr -rwzc 50 example.com
看三件事:
- 从哪一跳开始丢包
- 最后一跳是否稳定
- 中间跳
*是不是只禁 ICMP(终点能到就不算断)
别盯中间 * 恐慌,很多骨干设备对 ICMP 限优先级。
重点:丢包是不是“累积到终点还在”。
七、多节点 ping 检测的工程落地
最小闭环:
- 边缘机/探针机放 3–5 个地域
- 每 1min 跑 ICMP + TCPing 443
- 结果存时序库(Prometheus/SLS/自研)
- 看板按“节点×运营商×域名”切片
指标:
指标 |
用途 |
ICMP RTT p95 |
网络底噪 |
丢包率 |
链路稳定性 |
TCPing 成功率 |
端口真实可达 |
多节点一致性 |
是不是区域问题 |
基线偏离度 |
突发劣化早发现 |
八、排障 SOP(可直接抄)
text
1. 收工单:用户说“打不开” 2. 多节点 ping 检测:ICMP + 443 同跑 3. 拆结果: - 全红 → 源站/线路真断 - 单运营商红 → 调度/运营商出口 - ICMP 红 443 绿 → 只 ICMP 禁回 4. mtr 定位丢包跳 5. dig 看解析是否歪 6. curl 看业务返回 7. 派单:网络/安全/后端各认各的
九、什么别用 ping 检测干
- Ping 通就回“网络没问题”
- Ping 不通就重启 ECS
- 单机样本下全局结论
- 只看平均延迟不看抖动和丢包
- 把内网 IP 提交公共 ping 平台
- 告警只配“超时即罚”,不区分 ICMP 禁回
十、总结
ping 检测最被用歪的地方,是把它当“服务健康证明”。
它该是:
连通性漏斗的入口,不是终点。
ICMP 定“路在不在”,
TCPing 定“门开没开”,
curl 定“人接不接客”,
多节点定“是不是只有你这边坏”。
排障的本质不是证明“我没问题”,
是把“打不开”三个字,
缩成一句能派单的话:
“广东移动 ICMP 丢包 12%,443 正常,
不是源站挂,是出口链路抖,调 CDN 调度。”
一台机器 ping 得再绿,
也救不了一个把 ICMP 当健康检查的告警系统。