运维与审计 2026年4月27日

OpenClaw launchd:ThrottleInterval、KeepAlive 与健康探针——2026 租用 Mac mini 矩阵

VmMac Engineering Team 2026年4月27日 约 23 分钟阅读

在 VmMac 租用的 Apple Silicon Mac mini 上以 LaunchAgentOpenClaw 时,ThrottleInterval 可能掩盖崩溃循环,KeepAlive 会把「中毒」进程一次次拉起,而 SuccessfulExit 的语义又常与 Node 网关在升级时的退出码不一致。本文给出 2026 对照矩阵:安全组合、误报重启风暴、无头健康探测,以及与香港、日本、韩国、新加坡、美国一致的观测字段。请同时阅读 网关恢复预发布与生产隔离结构化日志与磁盘轮换,避免 plist 全靠猜。

基线路径见 安装与部署;访问与账号问题见 帮助;把金丝雀网关拆到独立机器时参考 定价

为什么 launchd 策略比 Node 版本号更重要

即便 OpenClaw 语义化版本钉死,只要健康探针把 LLM 延迟误判为宕机,launchd 仍可能每 12 秒 拉起一次网关。请把 plist 键当作 SLA 契约的一部分:它们定义操作系统如何理解成功、失败与退避。在 VmMac 没有虚拟机监管器——launchd 就是监管器

Node 网关还要遵守 macOS 信号语义:部署时的 SIGTERM 必须关闭 HTTP 服务、刷出结构化日志并在 launchd 升级到 SIGKILL 前退出。若进程因 WebSocket 悬挂而忽略 SIGTERM,你会看到交互 shell 里「手动重启永远成功」,而代理自动化却「飘忽」。把期望的信号阶梯写进与 Node LTS 同级的 README,并先在可丢弃的 VmMac mini 上演练,再动生产 plist。

最后,ThrottleInterval 不是修 bug 的替代品——它只改变失败尖叫的音量。请把 OS 级退避与应用级断路器配对,避免一次坏配置在五地同时把 CPU 打满。

  • ThrottleInterval:限制重启频率,但可能掩盖持续的部分不可用。
  • KeepAlive:保持常驻,却会让有计划的下线变复杂。
  • ExitTimeOut:决定优雅退出窗口,超时后才会 SIGKILL。

矩阵:ThrottleInterval、KeepAlive、ExitTimeOut 的取舍

目标 主旋钮 风险 缓解
阻止崩溃循环 ThrottleInterval ≥ 30s 真实崩溃后恢复变慢 与退出码外部分页配对
常驻网关 KeepAlive true + SuccessfulExit false 有意关机时仍被拉起 单独维护用 Label
优雅排空 ExitTimeOut 25–40s 卡死关机阻塞重启 预算后看门狗 SIGKILL
防止重启惊群 错开 StartCalendarInterval 或包装器随机 sleep 就绪晚于同伴 健康门等待依赖而非墙钟

当 OpenClaw 与用户会话里的其他 launchd 代理共存时,可在 plist 使用 NiceLowPriorityIO,避免失控日志船运饿死网关事件循环。它们不能替代容量规划,但能在局部事故中争取几分钟——足够 on-call 有意识地放宽 ThrottleInterval,而不是被误报风暴牵着走。

误报重启风暴:症状与根因

常见起点是健康检查打 localhost 时网关仍在绑定套接字,而磁盘压力拖长了模块加载。另一类是 Spotlight/mds 拉长冷启动,触发探针超时——请先对照 索引策略,再认定是 OpenClaw 自身问题。

护栏:若无预热门,探针间隔不要短于冷启动 p95 的 2 倍

另一类风暴来自依赖抖动:若探针先测外部 SaaS 再测本机就绪,日本或新加坡的路由抖动会把健康网关判死。请分层:外层监控先 loopback,再可选地以宽松超时采样外部金丝雀,不要把进程生命周期绑在你无法掌控的第三方 SLA 上。

磁盘写满会造成残酷假象:网关写 JSONL 直到 APFS 返回 ENOSPC,非零退出,KeepAlive 立刻复活,日志又立刻失败——有时快过 ThrottleInterval 降温。请把 日志轮换与磁盘预算 的护栏对齐,让重启因正确原因变慢。

无头健康探测:无需 VNC 的模式

用轻包装器对网关健康端口执行 curl——仅在回环上可关闭 TLS 校验——更好的是调用 OpenClaw 自带 CLI 状态子命令(若版本提供)。记录 HTTP 状态TLS 握手毫秒、以及探针后的 PID,让值班区分「进程在但卡死」与「进程已退出」。

若可行,让探针发送合成 X-Probe-Trace-Id 头并在网关日志回显,以便把探针失败与进程内慢查询缝合——这条关联技巧比任何 plist 微调都更能终结 P1。

curl -fsS --max-time 3 http://127.0.0.1:18789/health || exit 1

2026 八步调参阶梯

  1. 改 plist 前先采集 7 天基线退出码。
  2. 把 ThrottleInterval 调到能消灭任何低于 20s 的重启节奏。
  3. 让 ExitTimeOut 与文档化的优雅关机 SLA 对齐。
  4. 为每次重启写入结构化日志与原因码。
  5. 先在一个 VmMac 区域跑 72 小时金丝雀。
  6. 对比 HK、JP、KR、SG、US 的重启计数。
  7. 在 git 标签 launchd-YYYYMMDD 记录可回滚 plist。
  8. 季度演练:kill -9 网关并度量恢复。

在步骤四与五之间,即使指标全绿也要把金丝雀 Label 的功能冻结 72 小时——许多风暴只在周末流量形态出现。窗口内抓取 samplefootprint,对比各地 VmMac 节点的内存回归。

恢复类文章讲该重启什么;本文讲操作系统何时替你重启。若数字不一致,人类会失去信任并开始习惯性 kill -9。请让预发布与生产使用相同数值旋钮,参见 环境隔离,使晋升可 diff,而不是口口相传。

数值习惯:若每小时重启超过 6 次且持续 20 分钟 以上,应触发分页——这几乎从不只是「模型延迟波动」。

可观测性表:每次重启要记什么

字段 用途
launchd_exit_status 区分 OOM 与干净退出
uptime_s 发现「短命」循环
rss_mb 在 SIGKILL 前关联泄漏
fds_open 发现被 KeepAlive 放大的句柄泄漏
last_http_5xx_ts 把上游 5xx 与本地死亡分开

请把这些字段打成 JSON 行送到与网关请求相同的接收端,让 SRE 从「launchd 重启了作业」一键钻取到「RSS 超过基线 1.2×」。字段名在香港、日本、韩国、新加坡、美国保持一致,比第一版就追求完美基数更重要。

常见问题:Mac mini 上的 launchd 与 OpenClaw

要不要改成 LaunchDaemon? 仅在经过明确安全评审后——LaunchAgent 继承的用户 TCC 边界可能是你有意依赖的。

能按区域不同调参吗? 仅在有书面例外时;默认应保持一致。

升级 npm 依赖时呢? 迁移窗口临时放宽 ThrottleInterval。

SuccessfulExit false 是否等于「任何退出都重启」? 对多数网关实质如此——请用应用退出码区分排空完成与崩溃,否则蓝绿发布会与 launchd 打架。

健康探针应不应该用 root? 优先与网关同一用户上下文,文件权限与钥匙串/TCC 假设才能对齐;仅在只读探针确有需要时再提权。

已知维护如何降噪? 让包装器检查维护标记文件再失败探针,并给标记加自动过期,避免长假后被遗忘。

为什么 Mac mini M4 与 VmMac 适合常驻网关

Mac mini M4 的持续性能足以吸收偶发冷启动而不触发过激探针,统一内存也能降低相比超卖 VPS 的 OOM 抖动。VmMac 让你把网关放在香港、日本、韩国、新加坡、美国靠近用户与合规要求的位置,再租第二台 mini 专门做 plist 金丝雀,避免拿生产重启语义做实验。

租赁还缩短反馈环:当苹果推送可能微妙改变 launchd 行为的 macOS 安全补丁时,你可以先在非生产 mini 快照 plist 矩阵、打补丁并重放同一健康探针脚本,再触碰面向客户的自动化——这比一次深夜分页便宜得多。

生产前先金丝雀验证 plist

在新加坡或东京再租一台 VmMac Mac mini 验证 ThrottleInterval 变更,避免半夜叫醒值班。