代理心跳与存活判定
心跳是中心判断执行代理是否可用的主要依据:代理按固定周期上报自己的状态,中心在超过若干周期未收到心跳后把该代理标记为失联,并把它名下的在途任务重派给其他代理。设计要点有三:阈值取值通常至少覆盖三个周期,以容忍一次丢包与短暂抖动;要区分「进程活着」与「真的还能干活」,进程存在但任务线程全部卡住的代理仍会发心跳;失联后的动作要明确,包括摘除、重派与告警。重派的前提是任务幂等,否则一次误判就会造成重复执行。
基本信息
| 心跳周期 | 常见 10 到 60 秒,取决于可接受的故障发现时间 |
|---|---|
| 失联阈值 | 至少 3 个周期,避免单次抖动被误判为故障 |
| 状态取值 | online、degraded、offline、draining(排水) |
| 关键要求 | 判活要能区分进程存活与任务处理能力 |
典型使用场景
- 中心需要知道哪些代理当前可以接收新任务
- 代理异常退出后需要把在途任务重新派发
- 进程仍在但长时间无响应(假死)需要被识别
- 滚动维护前需要把代理置为排水状态,等在途完成
- 代理版本或配置不一致需要被及时发现
心跳上报与判定
心跳上报与判定
while true; do
load=$(cut -d' ' -f1 /proc/loadavg)
curl -sS -X POST -H 'Content-Type: application/json' \
-d "{\"agent\":\"$(hostname)\",\"load\":$load,\"inflight\":${n:-0}}" \
https://hub.example.com/v1/heartbeat
sleep 15 # 周期要显著小于失联阈值,留出重试余量
done
# systemd 看门狗:由系统判定进程是否仍在正常应答
# WatchdogSec=60
# 中心侧判定:now - last_seen 超过 3 倍周期才置为 offline代理状态与动作
| 状态 | 含义 | 中心应采取的动作 |
|---|---|---|
| online | 心跳正常且能接任务 | 正常派发 |
| degraded | 心跳正常但负载过高或上报异常 | 减少派发并观察 |
| offline | 超过阈值未收到心跳 | 摘除并重派在途任务 |
| draining | 主动排水,不再接新任务 | 等在途完成后下线 |
| 版本不符 | 心跳携带版本与期望不一致 | 告警并限制派发 |
判活要区分「进程活着」和「还能干活」。进程存在但任务线程卡死的代理仍会按时发心跳,需要用在途任务数、最近完成任务时间等辅助指标,否则中心会持续把新任务派给一个不会完成任务的节点。
失联阈值设得过短会把网络抖动当成节点故障,触发大量不必要的重派;设得过长则真故障期间任务长时间无人处理。阈值必须结合任务幂等能力与可接受的故障恢复时间一起确定。