ИИ / Автоматизация 19 мая 2026 г.

Сиротские дочерние процессы MCP OpenClaw на арендованном Mac mini: гигиена выхода и восстановление launchd (2026-05-19)

Инженерная команда ProxyMac 19 мая 2026 г. ~18 мин чтения

Команды, которые совмещают OpenClaw и MCP stdio на арендованных Mac mini M4 в регионах Гонконг, Япония, Корея, Сингапур и США через ProxyMac, иногда видят рост RSS в простое, лишние строки node или нестабильные инструменты после обновления шлюза. Заметка от 19.05.2026 отделяет скопление сирот от зависаний JSON-буфера, даёт матрицу оператора из пяти столбцов и девять шагов безопасной очистки под launchd. Дополнительно: параллельные агенты, stdio-буферизация, восстановление шлюза.

Симптомы: дрейф таблицы процессов до свопа

В открытых обсуждениях встречаются Node-дети, которые удерживают десятки мегабайт RSS после завершения родителя. На однотенантном железе это сразу видно в top.

  • Дрейф строк: после тихой ночи pgrep -lf mcp возвращает больше строк, чем после холодной загрузки.
  • Ступенчатая задержка: первые вызовы успешны, дальше очередь — классический «зомби»-читатель на трубе.
  • Разъезд версий: CLI новый, шлюз под LaunchAgent старый.
  • Ложный «падение модели»: задержка провайдера нормальна, а локальный fork забит.
Не путать: частичный JSON + ровный CPU ⇒ stdio-буфер. Сироты ⇒ RSS растёт в простое.

Причины: почему stdio MCP даёт «липкие» деревья

Stdio избегает случайных TCP-портов, но наследует POSIX: пока открыта любая сторона записи, EOF не приходит. npx может оставить внуков без оболочки. Среда LaunchAgent беднее интерактивной shell — короткие циклы перезапуска выглядят как атака на планировщик.

См. также ulimit и память: типичный мягкий лимит 2560 дескрипторов быстро исчерпывается, если каждый вызов инструмента открывает несколько труб.

Матрица оператора (сигнал → действие)

Главный сигналПервое действие (порядок важен)Архивные данныеОткат при ошибкеВладелец
~200 МБ RSS за ~20 мин без нагрузкиСначала экспорт ps -o pid,ppid,rss,commandЦепочка PPID + метки времени JSONLНе kickstart до маркировки родителяПлатформенный SRE
Двойной LISTEN на админ-портуВосстановление шлюза (один слушатель)lsof -nP -iTCP:18999 -sTCP:LISTENbootout конфликтующего plistЛид автоматизации
Лавина 429 при низком CPUСнизить параллелизм (руководство)429 на 5-минутное окноВернуть старый maxConcurrentTasksFinOps
RSS ровный, инструменты висятПроверить PTY/буфер, не SIGKILL сразуКороткий dtruss (если политика)Откатить unbuffer-флагиКлиентский инженер

Относитесь к каждому вмешательству как к мини-релизу: до первого сигнала зафиксируйте базовые метрики (средняя загрузка, свободное место APFS, число TCP-сессий к LLM). Если RSS растёт монотонно, а вызовов инструментов меньше 5 в минуту, причина почти всегда локальная. Сравните uptime шлюза и детей MCP — большой разрыв указывает на сирот.

На арендованном Mac mini M4 в регионах Гонконг, Токио, Сеул, Сингапур, США связывайте задержку с гигиеной процессов: заблокированная локальная труба выглядит как «медленная модель». После каждого инцидента заполняйте короткий постмортем с UTC-временной шкалой, цепочками PID, именами MCP-серверов и точным ярлыком launchctl — следующая эскалация пройдёт быстрее.

Если инстанс общий, стандартизируйте только безопасные команды (ps, pgrep, lsof с ограничением путей), а разрушительные шаги оставьте узкому дежурному кругу. Фиксируйте ожидаемую мажорную версию Node для шлюза и фактическую у каждого MCP — скачки мажора часто маскируются под «зависания».

Операционная цифра: если за 8 часов без новых серверов в конфигурации число процессов node с «mcp» или «modelcontextprotocol» в argv выросло более чем на 300 % относительно холодного старта, трактуйте это как гигиенический Sev-2, а не нормальную нагрузку.

В тикет прикладывайте не скриншоты графиков, а три числа: отношение числа node к холодному старту, RSS шлюза и вызовов инструментов в минуту. После инцидента сверяйте шаги со справкой по SSH и при повторяющихся симптомах рассмотрите отдельный mini из раздела тарифов — это часто дешевле бесконечных ночных «kill -9».

Девять шагов чистого прогона (SSH)

  1. Сообщить окно обслуживания — даже 90 с влияют на CI.
  2. Собрать доказательства: последние 500 строк лога шлюза + фрагмент launchctl print gui/$UID.
  3. Заморозить вход: вебхуки и планировщики на паузу.
  4. Карта PPID: не kill -9 для launchd-шлюза до классификации.
  5. Волна SIGTERM: подождать 15 с и пересчитать.
  6. SIGKILL только с проверенным argv.
  7. Перезапуск шлюза: launchctl kickstart -k или bootout/bootstrap по вендору.
  8. Дымовой тест: два вызова read-only, RSS за 10 мин к базовой линии.
  9. Постмортем: если еженедельно — приложить CSV PPID и ссылку на статью.
Для финансов: простаивающий шлюз M4 часто держит RSS заметно ниже 512 МБ; рост без трафика — про гигиену процессов, а не «тяжелее модель».

Дисциплина launchd: ThrottleInterval и перезапуск

ThrottleInterval, KeepAlive и SuccessfulExit задают агрессивность рестартов. Если заменить только Node, оставив старые stdio на мёртвом PTY, launchd увидит «здоровый» шлюз, а инструменты будут ломаться случайно. Проверяйте EffectiveUserID через launchctl print.

Разовые TCC/связка ключей — через VNC, затем снова безголовый режим по справке. Смешивать GUI-одобрения и ночные launchd-циклы часто удваивает MCP-серверы.

Профилактика: параллелизм, таймауты, радиус поражения

  • Логируйте глубину и возраст очереди; ориентир — параллельный OpenClaw.
  • Жёсткие таймауты: сеть начните с 120 с, лёгкие stat — с 15 с (ключи продукта уточняйте).
  • Отдельные рабочие каталоги для персон автоматизации.
  • Лабораторный mini отдельно от прода; регион HK/JP/KR/SG/US на странице тарифов.

Добавьте еженедельный сверочный проход: сопоставьте список MCP из конфигурации с фактическими argv на хосте. Процесс без записи в конфиге — риск и долг; запись в конфиге без процесса после объявленного выката — признак неуспешного старта. И то и другое оформляйте тикетом, а не «тихим» обходом, и фиксируйте владельца сервиса явно.

FAQ

Почему MCP stdio остаётся после остановки шлюза? Жёсткие падения, неполная цепочка SIGTERM или внуки Node от npx без промежуточной оболочки остаются живыми. LaunchAgent с KeepAlive поднимает новый шлюз, пока старые дескрипторы труб открыты — инструменты ведут себя нестабильно, хотя задержка модели в норме.

Можно ли убивать сирот MCP в продакшене на ProxyMac mini? Сначала SIGTERM, сохраните ps/lsof, проверьте argv, затем SIGKILL только при уверенности. На общем хосте проверьте открытые файлы, чтобы не снести сессию коллеги. После перезапуска убедитесь через lsof, что на админ-порту один LISTEN.

Чем это отличается от зависания stdio-буферизации? Буферизация даёт частичные JSON-строки при ровном CPU. Сироты копят RSS и лишние node-процессы в простое. Первое лечится PTY/флагами без буфера, второе — лимитами параллелизма, таймаутами и дисциплиной перезапуска шлюза.

Почему Mac mini ProxyMac удобнее сдерживать побочные эффекты MCP

Каждый вызов инструмента умножает fork и fd. Apple Silicon M4 даёт запас по однопоточной производительности, macOS совпадает с десктопной автоматизацией, узлы HK / JP / KR / SG / US приближают SaaS. Аренда позволяет «лабораторный» mini выбросить вместе с грязным деревом процессов, оформив его на той же странице тарифов, что и прод, без CAPEX. Процедуры согласуйте со справкой SSH/VNC.

Рискованный MCP изолируйте на выделенное железо

Аренда Mac mini HK/JP/KR/SG/US для лабораторий OpenClaw+MCP