4、主动探测技术:TCP 时延探测、HTTP 健康检查、ICMP 探测
聊到链路质量监测,被动监听固然重要,但很多时候,你得主动出击。
为什么?因为被动数据只能反映“已经发生”的问题。你想提前发现隐患,或者验证一条新链路的真实性能,就得靠主动探测。说白了,就是模拟用户流量,主动去“戳”一下网络,看它反应快不快、稳不稳。
我个人习惯把主动探测分为三类:TCP 时延探测、HTTP 健康检查、ICMP 探测。这三兄弟各有各的脾气,用对了地方,事半功倍。
4.1 ICMP 探测:最基础的“敲门砖”
ICMP 探测,大家最熟悉的就是 Ping 命令。它发一个 Echo Request,等对方回一个 Echo Reply。简单粗暴,用来判断目标是否可达、延迟高不高。
优点:轻量级,几乎所有的网络设备都支持。你不需要在目标上装任何 Agent。
缺点:也很明显。很多网络设备会限制 ICMP 的优先级,甚至直接丢弃。我在项目中遇到过好几次,Ping 的通,但业务就是卡。为什么?因为 ICMP 包走的路径和业务数据可能不一样,或者设备对 ICMP 做了限速。
ICMP 探测的典型用法:
# 基础 Ping,连续发 10 个包
ping -c 10 8.8.8.8
# 指定间隔和包大小,模拟大包场景
ping -c 100 -i 0.1 -s 1400 8.8.8.8
嗯,这里要注意,Ping 的包大小不要超过路径 MTU,否则会被分片,结果就不准了。
4.2 TCP 时延探测:更贴近业务的“温度计”
ICMP 不够准,那怎么办?用 TCP 探测。它模拟的是真正的 TCP 三次握手过程。你发一个 SYN,等对方回 SYN-ACK,你回 ACK。这个过程的耗时,就是 TCP 连接建立时间。
为什么说它更贴近业务?因为大部分应用层协议(HTTP、MySQL、Redis)都跑在 TCP 上。TCP 握手延迟,直接影响了用户的首次响应时间。
我常用的工具是 tcping 或者 hping3:
# 使用 tcping 探测 80 端口延迟
tcping -t 5 example.com 80
# 使用 hping3 模拟 SYN 探测
hping3 -S -p 443 -c 10 example.com
我个人习惯在探测时,记录下 最小延迟、最大延迟、平均延迟 和 丢包率。特别是丢包率,TCP 重传对用户体验的影响非常大。
| 指标 | ICMP 探测 | TCP 探测 |
|---|---|---|
| 协议层 | 网络层 (L3) | 传输层 (L4) |
| 模拟程度 | 低 | 高 |
| 受中间设备影响 | 大(可能被限速) | 小(更真实) |
| 典型工具 | ping | tcping, hping3 |
4.3 HTTP 健康检查:应用层的“体检报告”
TCP 探测能确认端口是否开放,但端口开了不代表服务正常。你想想看,Web 服务器可能还在启动中,或者数据库连接池满了,端口虽然开着,但返回的是 500 错误。
这时候就需要 HTTP 健康检查。它不仅仅是建立 TCP 连接,还会发送一个 HTTP 请求,检查返回的状态码、响应时间、甚至响应体内容。
我建议的检查策略:
- 状态码检查:期望返回 200 或 302,如果返回 5xx,立即告警。
- 响应时间检查:设置一个阈值,比如 500ms。超过这个时间,就算服务“亚健康”。
- 内容检查:检查响应体中是否包含特定的关键字,比如
OK或healthy。这能防止返回一个空壳页面。
/health 接口。这个接口不仅返回 200,还会检查依赖的数据库、缓存是否正常。这样,一次探测就能发现整个调用链的问题。
一个简单的 HTTP 健康检查脚本示例:
#!/bin/bash
# 简单的 HTTP 健康检查
URL="http://example.com/health"
EXPECTED_CODE=200
TIMEOUT=5
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout $TIMEOUT $URL)
if [ "$HTTP_CODE" -eq "$EXPECTED_CODE" ]; then
echo "✅ 服务正常,返回码: $HTTP_CODE"
else
echo "❌ 服务异常,返回码: $HTTP_CODE"
# 触发告警
fi
这里有个坑,curl 默认会跟随重定向。如果你期望的是 200,但服务返回了 302,curl 可能会返回最终页面的 200。所以,记得加上 -L 参数或者用 -o /dev/null 忽略响应体,只拿状态码。
4.4 三种探测的协同策略
在实际的监测系统中,我不会只用一种探测。我的做法是分层组合:
- ICMP 探测:作为第一道防线,每秒一次,快速发现网络不可达。
- TCP 探测:每 10 秒一次,确认关键端口是否开放,并记录握手延迟。
- HTTP 探测:每 30 秒一次,验证应用层是否正常响应。
为什么要这样设计?因为 ICMP 最轻量,可以高频执行,不会对网络造成太大负担。TCP 和 HTTP 相对重一些,频率可以降低。一旦 ICMP 发现丢包,我会立即触发一次 TCP 探测,确认是网络问题还是设备问题。
好了,这一节就聊到这里。下一节我们讲讲如何把这些探测数据收集起来,做可视化和告警。嗯,那才是真正头疼的地方。