OpenClaw launchd: ThrottleInterval, KeepAlive и health-пробы — матрица 2026 на арендованном Mac mini
Платформенные инженеры, запускающие OpenClaw под LaunchAgent на арендованном Mac mini Apple Silicon у VmMac, наследуют тонкие значения по умолчанию: ThrottleInterval скрывает циклы падений, KeepAlive воскрешает «отравленные» процессы, а семантика SuccessfulExit может расходиться с выходами Node во время обновлений. Матрица 2026 называет безопасные сочетания, показывает ложноположительные бури перезапусков, перечисляет headless-паттерны health-проб и связывает наблюдаемость с паритетом в Гонконге, Японии, Корее, Сингапуре и США. Читайте вместе восстановление шлюза, изоляцию staging и production и структурированные логи и ротацию диска, чтобы правки plist не превращались в угадайку.
Базовые пути: руководство по установке и развёртыванию; доступ: справка; отдельные canary-хосты: цены. Пики Spotlight/mds сопоставляйте с матрицей индексации и CI-диска, прежде чем винить OpenClaw.
Почему политика launchd важнее версии бинарника Node
Идеально зафиксированный semver OpenClaw бессилен, если launchd перезапускает шлюз каждые 12 секунд, потому что health-проба принимает задержку LLM за смерть процесса. Ключи plist — часть SLA: они задают, как ОС интерпретирует успех, ошибку и откат. Без гипервизорного супервизора у VmMac супервизор — launchd.
Node-шлюзы наследуют сигнальную семантику macOS: SIGTERM при деплое должен закрыть HTTP-серверы, сбросить структурированные логи и завершиться до эскалации launchd к SIGKILL. Если процесс игнорирует SIGTERM из‑за зависшего upstream WebSocket, в интерактивной оболочке видны «успешные» ручные рестарты, а у агентов — «дрожь». Задокументируйте ожидаемую лестницу сигналов в том же README, где закреплён Node LTS, и отрепетируйте на одноразовом mini VmMac до правок продовых plist.
ThrottleInterval не заменяет исправление багов — меняется лишь громкость сбоев. Сочетайте откат на уровне ОС с прикладными circuit breaker’ами, чтобы отравленная конфигурация модели не грузила CPU во всех регионах. По умолчанию одинаковые числа в Гонконге, Токио, Сеуле, Сингапуре и США; исключения — только письменно обоснованные эксперименты по задержке.
- ThrottleInterval ограничивает частоту рестартов, но может маскировать длительные частичные отказы.
- KeepAlive держит демоны резидентными, но усложняет draining при обновлениях.
- ExitTimeOut задаёт бюджет graceful shutdown до SIGKILL.
Матрица: ThrottleInterval vs KeepAlive vs ExitTimeOut
| Цель | Основная ручка | Риск | Смягчение |
|---|---|---|---|
| Остановить crash-loop | ThrottleInterval ≥ 30 с | Медленнее восстановление после реальных падений | Внешний пейджинг по коду выхода |
| Всегда включённый шлюз | KeepAlive true + SuccessfulExit false | Respawn при намеренном shutdown | Отдельный maintenance-label |
| Graceful drain | ExitTimeOut 25–40 с | Зависший shutdown блокирует рестарт | SIGKILL watchdog после бюджета |
| Избежать стада после reboot | Разнесённый StartCalendarInterval или случайный sleep в обёртке | Задержка готовности относительно пиров | Health-gate ждёт зависимости, не настенные часы |
Совместное размещение с другими агентами launchd: рассмотрите plist-Nice и LowPriorityIO, чтобы лог-шиппер не голодал цикл событий шлюза. Это не планирование ёмкости, но даёт минуты при частичных инцидентах — часто хватает, чтобы осознанно расширить ThrottleInterval.
Ложноположительные бури перезапусков: симптомы и причины
Бури часто начинаются, когда health бьёт в localhost, пока шлюз ещё не забиндил сокеты после дискового давления, замедлившего загрузку модулей. Другой шаблон — всплески Spotlight/mds, удлиняющие cold start сверх таймаута пробы — коррелируйте с политикой индексации.
Флаппинг зависимостей: если проба проверяет внешний SaaS до готовности loopback, микрорывки маршрутизации в Японии или Сингапуре помечают шлюз больным при живом процессе. Разделите пробы: сначала loopback, внешний canary — опционально с мягче таймаутами.
Полный диск: JSONL до ENOSPC, ненулевой выход, KeepAlive поднимает процесс, логи снова падают — иногда быстрее, чем ThrottleInterval остужает систему. Зеркалируйте дисковые предохранители из структурированной ротации логов.
Headless health-пробы без VNC
Небольшая обёртка curl’ит health-порт на loopback — проверку TLS отключайте только на loopback — или лучше CLI status OpenClaw. После пробы логируйте HTTP-статус, мс TLS-handshake и PID, чтобы дежурный отличил «процесс жив, но завис» от «процесс мёртв».
По возможности шлите синтетический заголовок X-Probe-Trace-Id и эхом в логах шлюза — это сшивает сбои пробы с медленными запросами сильнее любого твика plist.
curl -fsS --max-time 3 http://127.0.0.1:18789/health || exit 1
Восьмишаговая лестница настройки на 2026 год
- Семь дней собирать базовые коды выхода до смены plist.
- Выставить ThrottleInterval, остановив паттерн рестартов <20 с.
- Согласовать ExitTimeOut с документированным SLA graceful shutdown.
- Добавить структурированные логи на каждую причину рестарта.
- Canary 72 ч в одном регионе VmMac.
- Сравнить счётчики рестартов HK, JP, KR, SG, US.
- Задокументировать откат plist в git-теге
launchd-YYYYMMDD. - Квартальный game day:
kill -9и измерить восстановление.
Между шагами четыре и пять заморозьте фичи на canary-лейбле на 72 часа, даже если метрики зелёные — многие бури видны только в выходной форме трафика. Сохраняйте sample и footprint в окне canary для регрессий памяти между регионами.
Связь с runbook’ами восстановления шлюза
Статьи про восстановление говорят, что перезапускать; эта матрица — когда ОС должна перезапускать за вас. При расхождении цифр люди теряют доверие и привыкают к kill -9. Держите одинаковые числа в staging и prod согласно изоляции staging, чтобы промоушны были diffable.
Таблица наблюдаемости: поля на каждый рестарт
| Поле | Назначение |
|---|---|
launchd_exit_status |
Отличить OOM от чистого выхода |
uptime_s |
Петли младенческой смертности |
rss_mb |
Утечки до SIGKILL |
fds_open |
Утечки дескрипторов, усиленные keepalive |
last_http_5xx_ts |
Разделить upstream и локальную смерть |
Отправляйте поля JSONL в тот же sink, что и запросы шлюза, чтобы SRE переходил от «launchd перезапустил job» к «RSS превысил 1,2× базы». Согласованные имена в Гонконге, Японии, Корее, Сингапуре и США важнее идеальной кардинальности в первой итерации.
FAQ: launchd и OpenClaw на Mac mini
LaunchDaemon вместо LaunchAgent? Только после явного security-review — агенты наследуют границы TCC пользователя.
Тюнинг по регионам? Только с письменными исключениями; по умолчанию паритет.
Апгрейды? Временно расширяйте ThrottleInterval на npm-миграциях.
SuccessfulExit false всегда означает «рестарт на любой выход»? По сути да для большинства шлюзов — добавьте коды выхода drain vs crash.
Пробы от root? Предпочитайте тот же пользовательский контекст, что и у шлюза.
Заглушить алерты на обслуживание? Файл обслуживания в обёртке с автоистечением.
Почему Mac mini M4 и VmMac подходят для always-on шлюзов
Mac mini M4 даёт достаточно устойчивой производительности, чтобы пережить редкие cold start без ложных срабатываний агрессивных проб; unified memory снижает OOM-флапы относительно переподписанных VPS. VmMac размещает шлюзы в Гонконге, Японии, Корее, Сингапуре и США рядом с пользователями и требованиями резидентности данных — второй mini для экспериментов с plist без риска для продовой семантики рестартов.
Аренда сокращает цикл обратной связи, когда Apple в патчах macOS незаметно меняет launchd: снимите снапшот матрицы plist, примените патч на непрод mini, повторите тот же health-harness, затем трогайте клиентскую автоматизацию. Дешевле одной ночной страницы из-за недокументированной политики рестартов.
Канареечный plist перед продом
Арендуйте ещё один Mac mini VmMac в Сингапуре или Токио, чтобы проверить ThrottleInterval без ночных звонков.