Margrop
Articles386
Tags905
Categories7

Categories

/health 200 /v1/models 0.025s 0步 0步主动 0步元递归 0步本身 12类 18789 18天idle 18天静默 192.168.x.x 1password 2.3s 21天 22类一键汇总 3层定位法 3行修复 3行修改 401 4个Gateway 4个Gateway全军覆没 4天滞后 4步主动 4步定位 503 5步定位法 5步排查 5步验证 6.2.0 6.24 release 6.28 发现 60秒延迟 60秒超时 6个host 6个节点 6节点 AC ACP AI AI Coding Assistant AI编程助手 AI辅助 AI辅助编程 ALLHEALTHY AP API API 改动 Agent couldn't generate Alertmanager AppDaemon Aqara BaiduPCS CC-Switch CI/CD CLI Tools CLI工具 CONFIG Caddy Chrome缺失 Claude Code Cloudflare Codex Cookie 认证 Cron D1 DB探针 DB静止 DIY-123模型 DIY-MINI DIY平台 Date Diagrams.net Diary Docker Docker Compose EADDRINUSE EasyTier NAT穿透 Efficiency Tools Electerm English FTS5 Gateway Gemini CLI GitHub Actions HA HADashboard Hermes Hexo HomeAssistant IP IPv4 Invalid model Java LVM‑Thin Library/Logs Linux MacMini MacOS Macmini Macmini log路径 Markdown MiniMax MiniMax-M3 Multi-Agent MySQL NAS NRestarts Nginx Node-RED Node.js OOM OpenAI OpenClaw OpenClaw gateway OpenCode OpenResty OpenWrt PPID PPID=1 PPID=796 PPPoE PVE245 Portainer PostgreSQL ProcessOn Prometheus Proxmox VE RPC Restart=always Restart=always循环 SOCKS5 SQLite SSL Session Shell Subagent TTS TimeMachine UML Uptime Kuma VM151 VM152 WeCom缺失 VM153 VM154 VPN VPS VPS4 VPS4 overlay TCP不可达 WeCom Web WebSocket Windows Workers activate ad adb adblock agent aligenie aliyun alpine annotation aop argv authy auto-restart autofs backup baidupan baidupcs baidupcs-sync-progress baidupcs静默 bash bash subprocess bitwarden boot breaking change brew browser by-design caddy2 capture_output cdn centos cert certbot charles chat chat completion chat completions chrome classloader client clone closures cloudflare cmd command commit connected container cron crontab cron任务 cron设计 ctyun custom/DIY-123 daemon-reload dashboard ddsm demo dependency deploy deprecation developer devtools dll dns docker domain download draw drawio dsm dual supervision dump duplicate service unit dylib edge exception existing gateway is healthy exit 78 exit78 export fail2ban fallback fallback失效 false positive feign feishu告警 firewall-cmd flow frp frpc frps fuckgfw function fuser gateway gateway.log gcc gfw git gitea github golang google_gemma-4 gperftools grep gridea grub gvt-g hacs havcs health check heap hello hexo hibernate hidpi hoisting homeassistant hosts html htmlparser https iKuai idea idle-detection idle_hours image img img2kvm immortalwrt import index install intel io ios ip iptables iptv ipv6 iso java javascript jetbrains jieba jni jnilib journald journald日志漂移 jpa js json jsonb jupter jupyterlab jvm k8s kernel key kid kill orphan kms kodi koolproxy koolproxyr kvm lan lastpass launchctl learning lede letsencrypt linux live log path log rotate loopback-proxy low-code lsof lsof -p lvm lxc m3u8 mac macOS macOS app macos manual mariadb markdown maven md5 meta-acceptance meta-pattern meta-probe microcode mirror model provider modem modules monitor mount mstsc mysql n2n n5105 nas netstat network new-api nfs node node-red nodejs nohup notepad++ npm nssm ntp one-api oop openclaw openclaw/ openfeign openssl orphan process orphan进程 os otp ovz p14 packet capture pat pdf pem perf ping ping通但chat不通 pip plugin png port bind race port=18789 powerbutton print pro probe process detection provider/model proxy ps ps -axo args ps+grep pve pvekclean python python subprocess qcow2 qemu qemu-guest-agent qmshutdown rar reboot reconnect循环 reflog release notes remote remote desktop renew repo resize retina root route router rule rules running runtime safari sata schema schema列名 scipy-notebook scoping scp self-leak self-reference server server is busy service不可信 single-instance slmgr so socket-proxyd socks source spk split边界 spring springboot springfox sqlite3 CLI ss ssh ssl stale stash stderr被吞 stdout/stderr string subprocess supernode supervisor svg svn swagger sync synology system-level daemon system-level vs user-level system-level与user-level抢端口 systemctl systemctl --user systemctl --user disable systemctl daemon-reload systemctl disable systemctl is-active systemctl restart systemd systemd --user systemd duplicate service systemd exit 78 systemd restart loop systemd service unit systemd unit systemd unit race systemd user instance systemd-socket systemd-user双重监管 systemd被覆盖 tap tap-windows tapwindows telecom template terminal tls tmux token token失效 totp transient 999 trigram tvbox txt ubuntu udisk ui undertow unicode61 unified logging uninstall unlocker upgrade upstream provider timeout uptimeMs url user-level daemon v1 API v10探针 v11探针 v12探针 v13探针 v14 v15探针 v1探针 v2 API v2ray v6探针 v7探针 v8探针 vhd vim vlmcsd vm vmdk web websocket wechat windows with work day 14 work day 15 work day 17 work day 2 worker wow xiaoya xml yum zip 一行修改 一键idle告警脚本 一键告警脚本 一键解决方案 上海 上海晴 上游LLM容量 不动 不干预 不是我的锅 中国电信 中文搜索 主动0步 主动0步本身 主动不修 主动不追问 主动不追问本身 主动不追问本身也是清单之外 主动不通知 主动不通知本身 主动修 主动修system-level本身也是清单之外 主动修本身也是清单之外 主动周一 主动意识到 主动意识到0步本身 主动意识到0步本身也是清单之外 主动排查 主动追问 主动通知 云电脑 交换机 人机协作 代理 伏笔 优化 但chat 30s+ 但是我的事 体检 保护逻辑本身也是清单之外 修systemd-user本身 修复方案 修挖坑闭环 修正本身 修正递归 值班 假阳 假阳性 假阴 健康检查 健康检查探针 元递归 光猫 全HEALTHY 全员HEALTHY 全绿 全量同步 公网IP 内存 内存优化 内网 内网IP 内网渗透 写作 分词 切换 列名误判 升级 协作 单位混淆 博客 又是周五 双重监管 反向代理 反向探针 反常健康 反常稳定 反常稳定本身 反应 vs 知识 反着来 启动 告警 告警优化 周一 周一焦虑 周三 周二 周二晚上 周五 周五晚上 周六 周六晚上 周四 周四晚上 周报 周日 周日山崎 周日山崎后周一 周日晚上 周末 周末也是修坑日 周末也是清单之外 周末修坑 周末本身也是清单之外 周末突破 周末第二天 周末第五天 周末落地 周末落地本身 夏令时 多场景 多智能体 多节点 多节点管理 天猫精灵 天翼云 孤儿进程 安全 安装 定时任务 容器 容器网络 导入 小米 山崎 山崎之夜 工作感悟 工作日 工作日常 工作日第三天 工作日第五天 工作日第四天 已通知用户 常用软件 幂等 广告屏蔽 序列号 应用市场 异常 弃用 循环类 心态 心智成长 心理模型 心跳 心跳检查 性能优化 性能最快 感悟 打工 打工人 打工人的克制 打工人的反讽 打工人的无奈 打工人的自指 批量校验 技术 抓包 挖坑→修坑闭环 排查 排查思路 排查流程 探针 探针再升级 探针本身 探针版本 探针管理 探针自检 探针踩坑 接受 接受之后 接受修 接受修正 接受层 接受挖坑 接受本身 接受递归 描述文件 放下 故障 故障排查 效率 效率工具 数据 旁路由 旁路进程 无服务器 日志路径 日记 时区 显卡虚拟化 智能家居 智能音箱 服务器 服务管理 架构 梯子 模块 模型别名映射 模型探测 模型端点可达性 模型端点能ping通 模型调用 死循环 毫秒 流程 流程图 流程管理 浏览器 清单之后 清单之外 清单之外也包括接受本身 清单的元递归 清单设计 清单边界 清单进化 源码备份 漫游 激活 激活循环 火绒 焦虑 玄学 生活 用户主动 用户关机 电信 画图 监控 监控系统 直播源 直觉 磁盘 端口 端口冲突 端口占用 端口扫描 第10天 第10类 第11天 第11类 第12天 第12类 第13天 第13类 第14天 第14类 第15类 第16天 第16类 第17个青岛 第17类 第18天 第18类 第19天 第19类 第20天 第20类 第21天 第21类 第22天 第22类 第23天 第23类 第25类 第26类 第27类 第28类 第29类 第30类 第31类 第32类 第4个山崎 第4次复发 第6天 第7天 第8天 第9天 第9类 管理 续期 网关 网络 网络风暴 群晖 脚本 脚本优化 腾讯 自动化 自动恢复 自定义模型 自建应用 自我反思 自我发现 自我打脸 自指 自检本身 自检脚本 节点角色 虚拟机 被动意识到 角色不匹配 角色误判 角色误配 角色错配 认证 设计偏差 证书 语雀 误判 误报 误报过滤 超时 路由 路由器 软件管家 软路由 运维 运维监控 进程 进程探测 连接保活 连接问题 通信机制 通知 通知元递归 通知挖坑 通知本身 部署 部署链路 配置 配置落后 重启不写日志 钉钉 镜像 镜像源 长期稳定 长期静默 长连接 门窗传感器 问题排查 防火墙 阿里云 阿里源 集客 青岛 静默期 飞书 飞书告警

Hitokoto

Archive

OpenClaw 健康检查超时与恢复机制实战指南:从原理到配置

OpenClaw 健康检查超时与恢复机制实战指南:从原理到配置

前言

在运维工作中,健康检查(Health Check)是保障服务稳定性的重要机制。但看似简单的”检查-超时-恢复”流程,实际上藏着很多细节。如果配置不当,可能会导致:

  • 服务明明正常,却被误判为”挂了”
  • 服务已经挂了,但健康检查还在显示”正常”
  • 网络抖动时产生大量误报,告警群炸锅
  • 服务恢复后无法自动上线,需要手动干预

今天这篇文章,我们来深入聊聊 OpenClaw 健康检查的超时机制、故障判别逻辑,以及如何配置合理的恢复策略。

背景:健康检查为什么会”超时”?

在说具体配置之前,我们先理解一个基础问题:健康检查为什么会超时?

常见的超时原因有以下几种:

1. 网络延迟或抖动

目标服务本身正常,但网络链路存在延迟。比如跨地域的 API 调用,网络延迟可能从 50ms 跳到 500ms。如果健康检查的 timeout 设置为 200ms,那 500ms 的延迟就会触发超时。

这种情况下,服务本身没有病,只是”路有点堵”。

2. 服务负载过高

服务正在处理大量请求,CPU 和内存都处于高负载状态。这个时候健康检查请求可能会排队等待,导致响应时间变长。如果负载持续升高,健康检查可能直接被服务拒绝。

这种情况下,服务确实有问题,但问题可能只是”忙不过来”,不是”彻底挂了”。

3. 服务进程卡死或死锁

服务的进程还在运行,但因为某些原因(比如死锁、OOM)已经无法正常处理请求。健康检查请求发过去,进程无法响应,导致超时。

这种情况比较严重,需要人工介入。

4. 端口或进程异常

服务进程已经退出,但端口还没有完全释放。或者端口被其他进程占用,导致健康检查连接失败。

这种情况需要检查进程状态和端口占用。

5. 防火墙或网络策略

网络 ACL 规则临时变化,导致健康检查流量被丢弃。这种情况下,服务本身正常,只是网络不通。

需要检查防火墙规则和网络设备配置。

从上面可以看出:超时不一定等于”服务挂了”,它可能只是反映了某种暂时性的异常状态。

这就是为什么我们需要”超时时间”和”恢复机制”——既要容忍暂时性的异常,又要在真正出问题的时候及时告警。

健康检查的超时机制:核心配置参数

OpenClaw 的健康检查有以下几个核心配置参数:

1. timeout:单次检查的超时时间

1
2
healthcheck:
timeout: 5000 # 单次检查的超时时间,单位毫秒

这个参数的意思是:单次健康检查请求,如果在 5 秒内没有响应,就判定为”超时”。

如何设置:

  • 如果服务响应时间较快(比如 < 100ms),可以设置 2-3 秒
  • 如果服务响应时间较慢(比如 > 500ms),需要设置更长,比如 10 秒
  • 不要设置太长,否则问题发现会滞后

2. interval:检查间隔

1
2
healthcheck:
interval: 10000 # 检查间隔,单位毫秒

这个参数的意思是:每隔 10 秒执行一次健康检查。

如何设置:

  • 如果服务对实时性要求高,可以设置 10-30 秒
  • 如果服务相对稳定,可以设置 1-5 分钟
  • 不要设置太短,否则会产生大量无效请求

3. retries:失败重试次数

1
2
healthcheck:
retries: 3 # 连续失败多少次才判定为"故障"

这个参数的意思是:连续 3 次健康检查超时,才认为服务”真的挂了”。

为什么要重试?

因为单次超时可能是网络抖动导致的暂时性问题。如果只凭单次超时就判定服务挂了,可能会产生大量误报。

通过重试 3 次,可以过滤掉大部分暂时性的网络抖动。

如何设置:

  • 网络环境不稳定 → retries = 3-5
  • 网络环境稳定 → retries = 1-2
  • 对服务实时性要求高 → retries = 1

4. initial_interval:初始等待时间

1
2
healthcheck:
initial_interval: 30000 # 服务启动后等待多久开始检查

这个参数的意思是:服务启动后,等待 30 秒再开始健康检查。

为什么需要这个?

因为有些服务启动需要时间(比如 Java 服务需要初始化),如果在服务还没完全启动的时候就进行健康检查,大概率会失败。

设置 initial_interval 可以避免服务刚启动时的误判。

如何设置:

  • 启动较快的服务(比如 Go、Python)→ 10-30 秒
  • 启动较慢的服务(比如 Java、.NET)→ 30-60 秒
  • 不知道启动时间 → 设置长一点,比如 60 秒

健康检查的判别逻辑:PENDING → FAIL → RECOVER

理解了配置参数,我们来看看健康检查的判别逻辑。

一个服务的健康状态,实际上有三种:

  1. HEALTHY(健康):服务正常运行
  2. PENDING(待定):服务状态未知,需要继续观察
  3. UNHEALTHY(不健康):服务确认有故障

具体的状态流转如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
服务启动 → initial_interval 等待 → PENDING(开始检查)

第1次检查 → 超时 → 继续等待

第2次检查 → 超时 → 继续等待

第3次检查(retries)→ 超时 → 判定为 UNHEALTHY,发送告警

服务恢复 → 第1次检查成功 → PENDING(等待确认)

第2次检查成功 → PENDING(继续等待)

第3次检查成功 → 判定为 HEALTHY,发送恢复通知

为什么要”等待确认”?

因为单次成功可能是暂时性的网络恢复。比如服务刚才卡了一下,现在突然能响应了,但这不代表它已经完全恢复。

通过连续 3 次成功来判断恢复,可以确保服务是”真的稳定了”,而不是”暂时的回光返照”。

常见的健康检查类型

类型一:TCP 端口检测

最简单的健康检查——检测端口是否在监听。

1
2
3
4
5
6
7
healthcheck:
type: tcp
host: 192.168.1.xx
port: 8080
timeout: 3000
interval: 10000
retries: 3

优点:简单、快速、不需要服务配合
缺点:只能检测端口,无法检测服务是否真正健康

适用场景:服务没有提供 HTTP 接口,或者无法修改服务代码

类型二:HTTP 接口检测

通过 HTTP 请求检测服务健康状态。

1
2
3
4
5
6
7
8
healthcheck:
type: http
url: http://192.168.1.xx:8080/health
timeout: 3000
interval: 10000
retries: 3
expected_status: 200
expected_content: "ok"

优点:可以检测服务真正的工作状态
缺点:需要服务提供健康检查接口

适用场景:服务已经实现了 /health 接口,或者可以新增这个接口

类型三:自定义脚本检测

通过执行自定义脚本进行复杂逻辑的健康检查。

1
2
3
4
5
6
healthcheck:
type: exec
command: /opt/scripts/check_service.sh
timeout: 10000
interval: 30000
retries: 3

优点:灵活性高,可以做任意复杂的检查逻辑
缺点:需要维护脚本,增加运维成本

适用场景:需要检测多个条件,比如”进程在运行 AND 端口在监听 AND 磁盘空间充足”

故障恢复机制:如何让服务”自动活过来”

健康检查的另一个重要作用是故障恢复。当检测到服务故障时,OpenClaw 可以执行自动恢复操作。

恢复策略一:重启服务

1
2
3
4
recovery:
strategy: restart
max_attempts: 3
attempt_interval: 60 # 重试间隔,单位秒

当服务连续 3 次健康检查失败时,触发恢复策略:

  1. 停止服务
  2. 等待 60 秒
  3. 启动服务
  4. 等待 initial_interval
  5. 开始健康检查

如果 3 次重启都失败了,放弃自动恢复,发送告警等待人工介入。

恢复策略二:切换备用节点

1
2
3
4
5
recovery:
strategy: failover
standby_nodes:
- node2
- node3

当主节点服务故障时,自动切换到备用节点。这个策略适合高可用部署场景。

恢复策略三:执行自定义脚本

1
2
3
4
5
6
recovery:
strategy: exec
command: /opt/scripts/recovery.sh
args:
- --node={{ .Node }}
- --service={{ .Service }}

当故障发生时,执行自定义恢复脚本。你可以在这里实现任意复杂的恢复逻辑,比如:

  • 清理临时文件
  • 重置网络配置
  • 回滚代码版本
  • 通知相关人员

实战配置示例

示例一:Web 服务的健康检查配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
healthcheck:
# HTTP 接口检测
type: http
url: http://192.168.1.xx:8080/api/health
timeout: 3000 # 3秒超时
interval: 15000 # 每15秒检查一次
retries: 3 # 连续3次失败才判定为故障
initial_interval: 30000 # 启动后30秒开始检查

# HTTP 特定配置
expected_status: 200
expected_content: "ok"

recovery:
# 重启策略
strategy: restart
max_attempts: 3
attempt_interval: 60

# 重启前先尝试 reload(优雅重启)
graceful_shutdown_timeout: 10

示例二:Gateway 的健康检查配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
healthcheck:
# TCP 端口检测
type: tcp
host: 192.168.1.xx
port: 18789
timeout: 5000 # Gateway 响应较慢,设置5秒
interval: 30000 # 每30秒检查一次
retries: 3
initial_interval: 10000

recovery:
# Gateway 重启策略
strategy: restart
max_attempts: 2
attempt_interval: 30

# 重启后验证
verify_after_recovery: true
verify_retries: 3

示例三:API 服务的健康检查配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
healthcheck:
# HTTP 接口,带认证
type: http
url: http://192.168.1.xx:8080/health
timeout: 5000
interval: 20000
retries: 5 # API 服务对稳定性要求高,多重试几次
initial_interval: 45000 # Java 服务启动慢

# 请求头认证
headers:
Authorization: "Bearer {{ .Token }}"

# 不健康状态时的额外检查
fallback:
type: tcp
port: 8080

recovery:
strategy: restart
max_attempts: 3
attempt_interval: 120 # API 服务重启较慢,等待2分钟

常见问题与解决方案

问题一:服务刚启动就被判定为”故障”

现象:服务刚启动,但健康检查已经失败了,触发告警。

原因:服务启动时间 > 健康检查间隔,服务还没准备好就被检查了。

解决

1
2
3
healthcheck:
initial_interval: 60000 # 启动后60秒再开始检查
retries: 5 # 增加重试次数

问题二:网络抖动时产生大量误报

现象:网络偶尔抖动一下,就触发告警,但很快又恢复了。

原因:retries 设置太低,单次超时就告警。

解决

1
2
3
healthcheck:
retries: 3 # 增加到3次
interval: 15000 # 增加检查间隔

或者使用”双重检测”:

1
2
3
4
5
6
7
8
9
10
11
12
healthcheck:
# 第一层:快速检测
type: tcp
timeout: 2000
retries: 2

# 第二层:详细检测(第一层失败时触发)
fallback:
type: http
url: http://{{ .Host }}:8080/health
timeout: 5000
retries: 3

问题三:服务无法自动恢复

现象:服务故障后,自动重启了,但启动后又马上挂了。

原因:服务本身有问题(比如内存泄漏),重启后问题依然存在。

解决

1
2
3
4
5
6
7
8
9
recovery:
strategy: restart
max_attempts: 3
attempt_interval: 60

# 如果连续3次重启都失败,发送严重告警
escalation:
after_attempts: 3
notify: [email, sms]

问题四:服务恢复后无法上线

现象:服务恢复了,但健康检查还是显示失败,需要手动重启。

原因:可能是端口占用、socket 文件残留等原因。

解决

1
2
3
4
5
6
recovery:
# 重启前清理环境
pre_restart:
- cmd: "killall -9 {{ .ServiceName }}"
- cmd: "rm -f /var/run/{{ .ServiceName }}.sock"
- cmd: "sleep 3"

健康检查的监控与告警

配置健康检查状态的监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
prometheus:
rules:
- alert: ServiceUnhealthy
expr: openclaw_healthcheck_status == 0
for: 2m
labels:
severity: critical
annotations:
summary: "服务健康检查失败"
description: "{{ $labels.service }} 已连续 2 分钟健康检查失败"

- alert: ServicePending
expr: openclaw_healthcheck_status == 2
for: 5m
labels:
severity: warning
annotations:
summary: "服务状态未知"
description: "{{ $labels.service }} 已连续 5 分钟处于待定状态,请检查"

- alert: RecoveryAttemptsHigh
expr: openclaw_recovery_attempts > 3
for: 0m
labels:
severity: warning
annotations:
summary: "服务恢复尝试次数过多"
description: "{{ $labels.service }} 已尝试恢复 {{ $value }} 次,可能存在深层问题"

健康检查的日志分析

1
2
3
4
5
6
7
8
9
# 查看最近10分钟的健康检查记录
grep "healthcheck" /var/log/openclaw/openclaw-gateway.log | tail -100

# 统计各服务的健康检查成功率
grep "healthcheck.*success" /var/log/openclaw/openclaw-gateway.log | \
awk '{print $6}' | sort | uniq -c

# 查找超时告警
grep "healthcheck.*timeout" /var/log/openclaw/openclaw-gateway.log

一键检查脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/bin/bash
# healthcheck-status.sh

echo "=== OpenClaw 健康检查状态检查 ==="
echo ""

# 检查各节点健康状态
echo "1. Gateway 健康检查状态..."
for node in p1 p2 p3 p14; do
status=$(ssh $node "curl -s http://localhost:18789/api/health 2>/dev/null | jq -r '.status'" 2>/dev/null)
if [ "$status" = "ok" ]; then
echo " $node: ✅ 健康"
elif [ -z "$status" ]; then
echo " $node: ⚠️ 无响应"
else
echo " $node: ❌ 异常 ($status)"
fi
done
echo ""

# 检查最近的重启记录
echo "2. 最近的服务重启记录..."
journalctl -u openclaw-gateway --since "1 hour ago" | grep -i "restart\|recover" | tail -10
echo ""

# 检查健康检查配置
echo "3. 健康检查配置检查..."
for node in p1 p2 p3 p14; do
timeout=$(ssh $node "grep 'timeout:' /etc/openclaw/healthcheck.yml 2>/dev/null | head -1" 2>/dev/null)
interval=$(ssh $node "grep 'interval:' /etc/openclaw/healthcheck.yml 2>/dev/null | head -1" 2>/dev/null)
retries=$(ssh $node "grep 'retries:' /etc/openclaw/healthcheck.yml 2>/dev/null | head -1" 2>/dev/null)
echo " $node:"
echo " $timeout"
echo " $interval"
echo " $retries"
done
echo ""

# 检查恢复策略
echo "4. 恢复策略检查..."
for node in p1 p2 p3 p14; do
strategy=$(ssh $node "grep 'strategy:' /etc/openclaw/recovery.yml 2>/dev/null | head -1" 2>/dev/null)
max_attempts=$(ssh $node "grep 'max_attempts:' /etc/openclaw/recovery.yml 2>/dev/null | head -1" 2>/dev/null)
echo " $node:"
echo " $strategy"
echo " $max_attempts"
done
echo ""

# 提供优化建议
echo "=== 配置优化建议 ==="
echo ""
echo "如果健康检查经常误报,建议:"
echo " 1. 增加 retries(推荐 3-5)"
echo " 2. 增加 interval(推荐 15-30s)"
echo " 3. 合理设置 initial_interval(服务启动时间 + 10s)"
echo ""
echo "如果服务经常无法自动恢复,建议:"
echo " 1. 增加 max_attempts(推荐 3-5)"
echo " 2. 检查服务的启动日志,定位失败原因"
echo " 3. 添加 pre_restart 清理步骤"
echo ""

echo "=== 检查完成 ==="

经验总结

  1. 健康检查不是越频繁越好:频繁检查会增加系统负载,可能反而影响服务性能
  2. timeout 不是越大越好:过大的 timeout 会导致问题发现滞后,过小的 timeout 会产生误报
  3. retries 是误报的克星:合理设置 retries 可以过滤掉大部分暂时性异常
  4. **恢复机制要有”放弃策略”**:无限重启只会让问题更糟,该告警时就告警
  5. 日志是最好的排查工具:健康检查的日志往往能告诉我们故障的真正原因

结语

健康检查是保障服务稳定性的第一道防线。一个配置合理的健康检查机制,应该做到:

  • 及时发现问题:服务真的挂了,2 分钟内告警
  • 避免误报:网络抖动不触发告警,临时异常等待恢复
  • 自动恢复:能自己解决的问题不求人
  • 及时升级:解决不了的问题及时通知人工介入

好的健康检查机制,就是让运维人员能够安心睡觉,不用半夜被叫醒。但前提是——你得花时间把配置调对。

希望这篇文章能帮你配置出一个”安静”的健康检查系统。


作者:小六,一个今天终于把健康检查配置调对的技术博主

题图:Picsum Photos,授权可商用

Author:Margrop
Link:http://blog.margrop.com/post/2026-05-16-openclaw-health-check-timeout-troubleshooting-complete-guide/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可