Сиротские дочерние процессы MCP OpenClaw на арендованном Mac mini: гигиена выхода и восстановление launchd (2026-05-19)
Команды, которые совмещают OpenClaw и MCP stdio на арендованных Mac mini M4 в регионах Гонконг, Япония, Корея, Сингапур и США через ProxyMac, иногда видят рост RSS в простое, лишние строки node или нестабильные инструменты после обновления шлюза. Заметка от 19.05.2026 отделяет скопление сирот от зависаний JSON-буфера, даёт матрицу оператора из пяти столбцов и девять шагов безопасной очистки под launchd. Дополнительно: параллельные агенты, stdio-буферизация, восстановление шлюза.
Симптомы: дрейф таблицы процессов до свопа
В открытых обсуждениях встречаются Node-дети, которые удерживают десятки мегабайт RSS после завершения родителя. На однотенантном железе это сразу видно в top.
- Дрейф строк: после тихой ночи
pgrep -lf mcpвозвращает больше строк, чем после холодной загрузки. - Ступенчатая задержка: первые вызовы успешны, дальше очередь — классический «зомби»-читатель на трубе.
- Разъезд версий: CLI новый, шлюз под LaunchAgent старый.
- Ложный «падение модели»: задержка провайдера нормальна, а локальный fork забит.
Причины: почему 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:LISTEN | bootout конфликтующего plist | Лид автоматизации |
| Лавина 429 при низком CPU | Снизить параллелизм (руководство) | 429 на 5-минутное окно | Вернуть старый maxConcurrentTasks | FinOps |
| RSS ровный, инструменты висят | Проверить PTY/буфер, не SIGKILL сразу | Короткий dtruss (если политика) | Откатить unbuffer-флаги | Клиентский инженер |
Относитесь к каждому вмешательству как к мини-релизу: до первого сигнала зафиксируйте базовые метрики (средняя загрузка, свободное место APFS, число TCP-сессий к LLM). Если RSS растёт монотонно, а вызовов инструментов меньше 5 в минуту, причина почти всегда локальная. Сравните uptime шлюза и детей MCP — большой разрыв указывает на сирот.
На арендованном Mac mini M4 в регионах Гонконг, Токио, Сеул, Сингапур, США связывайте задержку с гигиеной процессов: заблокированная локальная труба выглядит как «медленная модель». После каждого инцидента заполняйте короткий постмортем с UTC-временной шкалой, цепочками PID, именами MCP-серверов и точным ярлыком launchctl — следующая эскалация пройдёт быстрее.
Если инстанс общий, стандартизируйте только безопасные команды (ps, pgrep, lsof с ограничением путей), а разрушительные шаги оставьте узкому дежурному кругу. Фиксируйте ожидаемую мажорную версию Node для шлюза и фактическую у каждого MCP — скачки мажора часто маскируются под «зависания».
node с «mcp» или «modelcontextprotocol» в argv выросло более чем на 300 % относительно холодного старта, трактуйте это как гигиенический Sev-2, а не нормальную нагрузку.
В тикет прикладывайте не скриншоты графиков, а три числа: отношение числа node к холодному старту, RSS шлюза и вызовов инструментов в минуту. После инцидента сверяйте шаги со справкой по SSH и при повторяющихся симптомах рассмотрите отдельный mini из раздела тарифов — это часто дешевле бесконечных ночных «kill -9».
Девять шагов чистого прогона (SSH)
- Сообщить окно обслуживания — даже 90 с влияют на CI.
- Собрать доказательства: последние 500 строк лога шлюза + фрагмент
launchctl print gui/$UID. - Заморозить вход: вебхуки и планировщики на паузу.
- Карта PPID: не
kill -9для launchd-шлюза до классификации. - Волна SIGTERM: подождать 15 с и пересчитать.
- SIGKILL только с проверенным argv.
- Перезапуск шлюза:
launchctl kickstart -kили bootout/bootstrap по вендору. - Дымовой тест: два вызова read-only, RSS за 10 мин к базовой линии.
- Постмортем: если еженедельно — приложить CSV PPID и ссылку на статью.
Дисциплина 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