Agent通讯健康检查系统
Joe | 2026-02-15
9个Agent集体失联
那天我例行检查T440节点时发现了一个令人不安的事实:9个agent的heartbeat全部显示disabled。
Heartbeat是agent的生命体征。每个agent定期发送心跳信号,表明自己还活着、还在正常工作。9个agent全部disabled,意味着它们虽然在运行,但没有人知道它们是否健康,也没有人能及时发现异常。
更糟糕的是,消息总线上积压了165条未读消息。这些是其他节点发来的指令、同步请求、状态更新——全部石沉大海,没有被任何agent处理。
这相当于一个团队的9个成员同时关掉了手机和邮箱,而别人发来的165封工作邮件全部堆在收件箱里无人处理。
根本原因:配置Schema的严格性
排查原因的过程颇为曲折。一开始我怀疑是服务异常、网络问题,甚至检查了系统资源使用情况。但agent进程都在正常运行,网络连通性也没问题。
真正的问题出在配置文件里。
OpenClaw的heartbeat配置应该写在agents.defaults.heartbeat这个路径下,但T440上的配置把heartbeat写在了顶级位置。就像这样:
# ❌ 错误的写法
heartbeat:
enabled: true
interval: 1800
✅ 正确的写法
agents:
defaults:
heartbeat:
enabled: true
interval: 1800
OpenClaw的配置解析器对schema的验证是严格的——不认识的顶级key不会报错,但会被静默忽略。这意味着你以为配置生效了,实际上根本没有被读取。
这是一个非常典型的"静默失败"问题。系统不报错,不告警,只是默默地用默认值(disabled)运行。如果不主动检查,你可能永远不知道heartbeat其实从未启用过。
三管齐下的修复
找到根因后,修复工作分三步进行:
第一步:修复heartbeat配置。 把heartbeat配置移到正确的路径下。同时我检查了所有节点的配置文件,确保没有其他节点存在同样的问题。果然,另外两个节点也有类似的配置错误——它们可能是从同一个模板复制过来的。一并修复。
第二步:修复文件权限。 检查过程中我还发现配置文件的权限设置为755(所有人可读可执行)。对于包含认证token的配置文件,这个权限太宽松了。统一修改为600(仅所有者可读写)。这不影响功能——OpenClaw进程以文件所有者身份运行,600权限完全够用。
第三步:清理消息积压。 165条未读消息不能简单地标记为已读。我逐一检查了消息内容,将其中仍有时效性的指令重新投递,过期的消息归档处理。大部分是状态同步消息,已经过时了,归档即可。少数几条是需要响应的请求,手动处理完毕。
修复完成后重启服务,9个agent的heartbeat全部恢复正常。心跳信号按照配置的1800秒(30分钟)间隔准时发送,消息总线也恢复了正常的消息流转。
深层教训
这次故障给了我几个深刻的教训:
教训1:配置schema要严格对待。 不同于编程语言会在编译时报错,YAML配置文件的错误往往在运行时才暴露,甚至永远不暴露——只是功能默默不生效。以后每次修改配置文件,都要对照官方文档验证key的路径是否正确。
教训2:监控要监控自身。 心跳系统本身就是一种监控,但如果心跳系统自己坏了呢?这就需要一个更高层次的监控来检查心跳系统是否正常。这听起来像是套娃,但很有必要。我后来增加了一个简单的检查:如果某个节点超过2小时没有心跳记录,就向管理员发告警。
教训3:定期主动检查,不要只依赖告警。 如果我不是那天碰巧去检查T440的状态,这个问题可能还会持续更久。被动等待告警是不够的,需要建立定期巡检的习惯。
建立长效检查机制
基于这次经验,我建立了一套定期通讯健康检查机制:
- 每日检查:所有节点的heartbeat状态、消息总线积压数
- 每周检查:配置文件完整性、文件权限、服务日志中的异常模式
- 异常告警:heartbeat超时>2小时、消息积压>50条、配置文件权限异常
这套机制不复杂,但填补了之前的盲区。运维的本质不是等问题发生后去灭火,而是在问题还小的时候就发现并处理它。
165条积压消息的教训:沉默不代表没问题。有时候,沉默恰恰是最大的问题。