OpenClaw launchd:ThrottleInterval、KeepAlive 与健康探针——2026 租用 Mac mini 矩阵
在 VmMac 租用的 Apple Silicon Mac mini 上以 LaunchAgent 跑 OpenClaw 时,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 使用 Nice 与 LowPriorityIO,避免失控日志船运饿死网关事件循环。它们不能替代容量规划,但能在局部事故中争取几分钟——足够 on-call 有意识地放宽 ThrottleInterval,而不是被误报风暴牵着走。
误报重启风暴:症状与根因
常见起点是健康检查打 localhost 时网关仍在绑定套接字,而磁盘压力拖长了模块加载。另一类是 Spotlight/mds 拉长冷启动,触发探针超时——请先对照 索引策略,再认定是 OpenClaw 自身问题。
另一类风暴来自依赖抖动:若探针先测外部 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 八步调参阶梯
- 改 plist 前先采集 7 天基线退出码。
- 把 ThrottleInterval 调到能消灭任何低于 20s 的重启节奏。
- 让 ExitTimeOut 与文档化的优雅关机 SLA 对齐。
- 为每次重启写入结构化日志与原因码。
- 先在一个 VmMac 区域跑 72 小时金丝雀。
- 对比 HK、JP、KR、SG、US 的重启计数。
- 在 git 标签
launchd-YYYYMMDD记录可回滚 plist。 - 季度演练:
kill -9网关并度量恢复。
在步骤四与五之间,即使指标全绿也要把金丝雀 Label 的功能冻结 72 小时——许多风暴只在周末流量形态出现。窗口内抓取 sample 与 footprint,对比各地 VmMac 节点的内存回归。
与网关恢复手册如何衔接
恢复类文章讲该重启什么;本文讲操作系统何时替你重启。若数字不一致,人类会失去信任并开始习惯性 kill -9。请让预发布与生产使用相同数值旋钮,参见 环境隔离,使晋升可 diff,而不是口口相传。
可观测性表:每次重启要记什么
| 字段 | 用途 |
|---|---|
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 矩阵、打补丁并重放同一健康探针脚本,再触碰面向客户的自动化——这比一次深夜分页便宜得多。