2. 健康检查机制:心跳检测、探活、就绪检查的原理与实现
边缘节点的故障自愈,第一步是什么?
不是修复,是发现。
你想想看,节点都挂了,你还在那分析日志、调参数,那不是白忙活吗?所以,健康检查机制就是整个自愈体系的「眼睛」。没有它,后面所有的策略都是盲人摸象。
今天咱们就聊聊三种最核心的检查机制:心跳检测、探活、就绪检查。这三兄弟各有各的脾气,用错了地方,反而会添乱。
2.1 心跳检测(Heartbeat)—— 最朴素的「你还活着吗?」
心跳检测,说白了就是节点定期向中心报告:「我还活着,一切正常。」
我在项目中遇到过一种情况:某个边缘节点网络偶尔抖动,但业务其实没断。结果心跳超时,系统直接把它踢出集群了。后来我加了个「心跳容忍窗口」,允许丢两三次心跳再判定死亡,这才消停。
- 节点每隔 N 秒发送一次心跳信号
- 中心节点记录最后一次心跳时间
- 如果超过 T 秒没收到,标记为「疑似故障」
- 连续 M 次未收到,标记为「故障」
代码实现其实不复杂。我习惯用轻量级的 UDP 或简单的 HTTP GET 来做心跳。下面是一个伪代码示例:
// 边缘节点端
while (true) {
sendHeartbeat("node-001", "alive");
sleep(5); // 每5秒发一次
}
// 中心端
function checkHeartbeat(nodeId) {
lastTime = getLastHeartbeatTime(nodeId);
if (now() - lastTime > 15) { // 15秒没收到
markSuspect(nodeId);
}
if (now() - lastTime > 30) { // 30秒没收到
markFailed(nodeId);
triggerAutoHeal(nodeId);
}
}
2.2 探活(Liveness Probe)—— 进程活着不代表业务活着
心跳检测只能告诉你「进程在不在」,但进程活着不代表业务正常。
我曾经遇到一个案例:边缘节点的 Java 进程还在,但 JVM 已经 Full GC 卡死了,业务完全不可用。心跳还在发,但用户已经骂翻了天。
这就是探活要解决的问题。它会主动去检查进程内部的状态,比如:
- 进程是否响应特定端口
- 进程是否能处理简单的请求
- 进程内部的关键线程是否还活着
在 Kubernetes 里,探活 Probe 是这样配置的:
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 5
failureThreshold: 3
这段配置的意思是:容器启动后等10秒,然后每5秒访问一次 /healthz 接口。连续3次失败,K8s 就会重启这个容器。
2.3 就绪检查(Readiness Probe)—— 别把流量引给「半死不活」的节点
探活决定「要不要重启」,就绪检查决定「要不要转发流量」。
你想想看,一个节点刚启动,缓存还没预热,数据库连接池还没建好,这时候把用户请求打过去,那不是找死吗?
就绪检查就是干这个的。它告诉负载均衡器:「我准备好了,可以接客了。」
K8s 里的配置长这样:
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
这个配置检查 8080 端口的 TCP 连接是否正常。一旦连续3次失败,K8s 就会把这个 Pod 从 Service 的 Endpoint 里移除,流量就不会再打过来了。
| 检查类型 | 检查对象 | 失败后果 | 典型场景 |
|---|---|---|---|
| 心跳检测 | 节点/进程是否存在 | 标记为故障,触发自愈 | 边缘节点与中心通信 |
| 探活 | 进程内部是否健康 | 重启容器/进程 | 应用卡死、死锁 |
| 就绪检查 | 服务是否可接受流量 | 从负载均衡中移除 | 启动预热、临时过载 |
2.4 三种检查的协同工作
这三种检查不是互斥的,而是互补的。我习惯把它们组合起来用:
- 心跳检测:负责节点级别的存活,超时了就触发节点迁移或重启
- 探活:负责进程级别的健康,挂了就自动拉起
- 就绪检查:负责流量级别的可用,没准备好就不让进流量
举个例子:一个边缘节点突然网络闪断,心跳丢了两次,但很快恢复了。这时候心跳检测可能会标记「疑似」,但探活和就绪检查都正常,所以不会触发重启。如果心跳连续丢了5次,那就判定节点挂了,直接触发节点迁移。
2.5 实现时的几个关键参数
嗯,这里要注意几个参数,调不好会出大问题:
- initialDelaySeconds:启动延迟。别设太短,应用还没启动完就开始检查,肯定失败。我一般设 10-30 秒,看应用启动速度。
- periodSeconds:检查间隔。太频繁浪费资源,太慢反应迟钝。5-15 秒比较合理。
- failureThreshold:失败阈值。边缘网络不稳定,建议设 3-5 次,避免网络抖动就误判。
- successThreshold:成功阈值。就绪检查一般设 1 次,探活可以设 1-2 次。
下面这张图展示了三种检查在边缘节点上的协作流程:
说白了,这三种检查机制就是边缘节点自愈的「三道防线」。心跳检测看节点在不在,探活看进程好不好,就绪检查看服务能不能用。把它们配合好,边缘节点的故障自愈就有了坚实的基础。