4、主动探测技术:TCP 时延探测、HTTP 健康检查、ICMP 探测

聊到链路质量监测,被动监听固然重要,但很多时候,你得主动出击。

为什么?因为被动数据只能反映“已经发生”的问题。你想提前发现隐患,或者验证一条新链路的真实性能,就得靠主动探测。说白了,就是模拟用户流量,主动去“戳”一下网络,看它反应快不快、稳不稳。

我个人习惯把主动探测分为三类:TCP 时延探测、HTTP 健康检查、ICMP 探测。这三兄弟各有各的脾气,用对了地方,事半功倍。

4.1 ICMP 探测:最基础的“敲门砖”

ICMP 探测,大家最熟悉的就是 Ping 命令。它发一个 Echo Request,等对方回一个 Echo Reply。简单粗暴,用来判断目标是否可达、延迟高不高。

优点:轻量级,几乎所有的网络设备都支持。你不需要在目标上装任何 Agent。

缺点:也很明显。很多网络设备会限制 ICMP 的优先级,甚至直接丢弃。我在项目中遇到过好几次,Ping 的通,但业务就是卡。为什么?因为 ICMP 包走的路径和业务数据可能不一样,或者设备对 ICMP 做了限速。

⚠️ 避坑指南:我曾经在一个跨国专线项目中,Ping 延迟只有 20ms,但文件传输慢得像蜗牛。后来发现,运营商的 MPLS 网络对 ICMP 做了特殊处理,优先级很高,但 TCP 业务流量却被排队了。所以,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 握手延迟,直接影响了用户的首次响应时间。

💡 核心要点:TCP 时延探测能反映出中间防火墙、负载均衡器对 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。超过这个时间,就算服务“亚健康”。
  • 内容检查:检查响应体中是否包含特定的关键字,比如 OKhealthy。这能防止返回一个空壳页面。
🔧 实战技巧:我在做微服务健康检查时,会专门设计一个 /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 三种探测的协同策略

在实际的监测系统中,我不会只用一种探测。我的做法是分层组合:

  1. ICMP 探测:作为第一道防线,每秒一次,快速发现网络不可达。
  2. TCP 探测:每 10 秒一次,确认关键端口是否开放,并记录握手延迟。
  3. HTTP 探测:每 30 秒一次,验证应用层是否正常响应。

为什么要这样设计?因为 ICMP 最轻量,可以高频执行,不会对网络造成太大负担。TCP 和 HTTP 相对重一些,频率可以降低。一旦 ICMP 发现丢包,我会立即触发一次 TCP 探测,确认是网络问题还是设备问题。

📌 总结一下:主动探测不是越复杂越好,而是越贴近业务越好。ICMP 看连通性,TCP 看握手质量,HTTP 看服务健康度。三者结合,才能构建一个立体的监测体系。

好了,这一节就聊到这里。下一节我们讲讲如何把这些探测数据收集起来,做可视化和告警。嗯,那才是真正头疼的地方。