DevOps и аудит 15 мая 2026

2026-05-15 LaunchAgent OpenClaw: ThrottleInterval, KeepAlive и SuccessfulExit на арендованном ProxyMac Mac mini — не путать циклы падений с отказом модели

Команда инженеров ProxyMac 2026-05-15 ~18 мин чтения

Команды, которые запускают OpenClaw как LaunchAgent на арендованных Mac mini M4 в Гонконге, Японии, Корее, Сингапуре или США, часто видят сценарий: шлюз завершается, launchd поднимает его быстрее секунды, API инференса отвечает 429 или пустыми потоками, и все винят «модель». Статья для эксплуатации и платформенных инженеров: (1) фильтр аудитории и количественные пороги, (2) разделение циклов падений и провайдерского throttling, (3) четырёхстрочная матрица решений для ThrottleInterval, KeepAlive и SuccessfulExit, (4) девятиступенчатый runbook в духе восстановления после перезапуска и изоляции dev/staging/prod, (5) таблица сценариев для всплесков HTTP 429, (6) ловушки при ThrottleInterval 0. Дополнительно: ulimit и память, фоновые задания, корпоративный HTTP-прокси в plist. SKU — на странице цен, шаблоны инцидентов — в справке, разовые GUI-диалоги доверия — через VNC.

Кому обязательно настраивать ThrottleInterval и KeepAlive для OpenClaw

Начинайте там, где шлюз может завершиться по причинам, не связанным с качеством модели: повреждённый JSON конфигурации, segfault дочернего MCP, ротация TLS MITM или исчезновение token-файла в середине выката. Если в plist LaunchAgent нет ThrottleInterval, macOS может разрешить настолько плотные автоперезапуски, что ни один оператор в SSH не повторил бы так. Наоборот, только KeepAlive без явной семантики выхода может мгновенно поднять «успешную» остановку на техобслуживание.

  • Количественный порог: если log show --predicate 'process == "launchd"' --last 15m показывает больше 12 стартов одного label — это зона цикла падений.
  • Порог провайдера: если 429 коррелируют с метками времени перезапуска в пределах ±5 с, сначала замедлите автоперезапуски, а не температуру модели.
  • Порог изоляции: среды не делят один label plist — до правок throttle примените правило «одна среда — один label» из гайда по изоляции.

Симптомы: циклы падений vs провайдерский throttling

Циклы падений часто дают пилообразную загрузку CPU: 0 % простоя, 180 % за ~8 с загрузки OpenClaw, жёсткий выход, повтор. Провайдерский throttling держит CPU ровнее, в логах встречаются retry-after или подсказки экспоненциального backoff. JSONL с одинаковыми первыми баннерами во многих файлах намекает, что процесс не доходит до устойчивого состояния. Прежде чем открывать тикет у вендора, сверьте каденцию перезапусков с временем изменения plist через stat -f '%m' ~/Library/LaunchAgents/com.example.openclaw.plist и сравните с JSONL-диагностикой.

Тройка доказательств: (1) последний код выхода через launchctl print, (2) гистограмма HTTP в логах шлюза, (3) коды выхода детей MCP — если MCP стабилен, а HTTP преимущественно 429, сначала душите автоперезапуски.

Матрица: ThrottleInterval, KeepAlive и SuccessfulExit

Переключатель Что контролирует Когда повышать / включать Главный риск при ошибке
ThrottleInterval (секунды) Минимальный интервал между автоперезапусками после выхода После штормов 429 или нестабильного MCP на выкате Слишком большое значение маскирует реальное восстановление
KeepAlive true Автоподъём при выходе процесса (по семантике plist) Долгоживущие шлюзы, которые должны пережить ребуты Бесконечный respawn без throttle сжигает квоты
SuccessfulExit false С KeepAlive: выход 0 как успех без автоперезапуска Техокна со скриптами-сентинелами Неверный bool оставляет зомби-циклы
Ручной launchctl kickstart -k Перезапуск оператором вне cadence throttle Контролируемый выкат после проверки plist Автоматизация с tight-loop kickstart воспроизводит шторм

Девятиступенчатый runbook стабилизации

  1. Аудит label: только один plist владеет prod OpenClaw согласно изоляции сред.
  2. Сбор шторма выходов: экспорт последних 200 строк unified log с фильтром по label.
  3. Базовый throttle: в dev начать с 10 с, в prod после первого кластера 429 — 30 с.
  4. Определить SuccessfulExit: задокументировать выход 0 как graceful в скриптах апгрейда.
  5. Согласовать потолки памяти: с статьёй про ulimit, чтобы OOM не выглядел как сеть.
  6. Подавление webhook: при Slack дебаунсить алерты, пока throttle охлаждает процесс.
  7. Инъекция сбоя: временно убрать не-секретный конфиг и убедиться, что интервал соблюдает ThrottleInterval.
  8. Soak: 45 минут синтетики на 40 % пикового параллелизма, чтобы поймать внешний watchdog с двойным стартом.
  9. Постмортем: diff plist и гистограмму перезапусков в тот же Git, что и версионирование конфигов.
Никогда не ставьте ThrottleInterval в 0 на общих арендованных mini с продакшен-ключами API — ваш краш станет чужой историей rate limit.

Таблица сценариев: всплески HTTP 429 и поведение launchd

Сценарий Наблюдаемый паттерн Первый рычаг
Цикл segfault MCP Код 139 каждые 2–4 с ThrottleInterval 30; исправить путь MCP
Гонка token-файла на выкате 6 выходов 78, затем успех Мьютекс выката; ThrottleInterval ≥ 15
Глобальный throttle провайдера 429 с Retry-After: 60 ThrottleInterval ≥ 60; снизить параллель агентов
Баг скрипта kickstart -k Старт каждые 60 с даже при здоровье Убрать cron-обёртку; KeepAlive + health probe

Ловушки: нулевой ThrottleInterval и двойные watchdog

Часть скопированных plist наследует ThrottleInterval 0 из шаблонов для интерактивных демонов. OpenClaw плюс агрессивный KeepAlive даёт субсекундные штормы и исчерпание файловых дескрипторов — наружу это как ошибки MCP 24 без логической поломки инструмента. Второй риск: внешний cron вызывает launchctl kickstart, пока KeepAlive true, и удваивает старт в здоровые периоды. Один слой надзора.

defaults read /path/to.plist ThrottleInterval

FAQ

Замедляет ли ThrottleInterval обычные выкаты? Он ограничивает только минимальный интервал между автоматическими перезапусками после выхода. Ручной launchctl kickstart оператором не попадает под throttle.

Держать ли KeepAlive true на canary? Часто да для долгих шлюзов, но вместе с ThrottleInterval; canary — отдельный label plist.

Какой код для SuccessfulExit на техработах? Сентинел обёртки — обычно 0 — документировать рядом с plist.

Почему ProxyMac Mac mini — правильное место для дисциплины перезапусков launchd

Арендованные Mac mini M4 дают предсказуемый single-tenant CPU, чтобы отделить тепловой throttle от штормов перезапуска, нативный macOS-syslog как на ноутбуках разработчиков и выбор региона HK / JP / KR / SG / US, чтобы тесты задержки были ближе к реальным пользователям. После проверки математики throttle те же фрагменты plist можно промоутить через прозрачные цены на вторую mini, а не гадать на общих CI runner, где launchd скрыт.

Укрепить OpenClaw launchd до укуса квот

ThrottleInterval · KeepAlive · HK / JP / KR / SG / US