Почему общий шлюз «ломается» и как узлы договариваются не перегружать его
Общий шлюз — это одна точка входа (или компактная HA-пара), куда сходятся GitHub Actions, Matrix/Teams и долгоживущие агенты на каждом Mac. Без явных бюджетов нагрузки эти потоки складываются: десять узлов по два параллельных job дают двадцать одновременных сессий к одному процессу, даже если очередь за шлюзом ещё жива. Для коллаборации мультиузла нужны три соглашения: опубликованная модель ёмкости (RPS и максимум сессий), согласованные лимиты на стороне CI и диспетчеров сообщений, и идентичные параметры лимитеров на всех репликах шлюза за балансировщиком. Зафиксируйте бюджет в runbook: кто может менять лимиты, как пересчитывать сумму параллелизма по узлам и какой запас оставлять под ручные запуски и инциденты. Случайный джиттер в cron и в расписании workflow снижает вероятность одновременного «ударя» шлюза в начале часа. Базовую схему распределения и отказоустойчивости разберите в руководстве по балансировке и failover OpenClaw на MeshMac; где вешать HTTP-модули ограничения на краю — в матрице Nginx vs Caddy для TLS-прокси.
Пошагово: проектирование лимитов на шлюзе
- Инвентаризация маршрутов. Перечислите HTTP-пути или методы шлюза. Пометьте классы
interactive,ci_ingest,internal_worker— это вашroute_classв логах. - Идентичность для ключа лимита. IP, API key, OAuth subject или заголовок
tenant_idиз CI. Стабильный ключ изолирует шумных соседей. - Два числа на класс. (а) устойчивые запросы в секунду с допуском на краткий всплеск — токен-бакет; (б) максимум одновременных сессий или исходящих соединений — семафор / потолок соединений.
- Очередь за шлюзом. Контроль допуска на входе должен быть жёстче, чем неконтролируемый рост глубины очереди: отсекать на краю дешевле, чем разбирать «отравленные» задачи. Политику повторов согласуйте с гайдом по очереди задач и повторам OpenClaw.
- Тёмный запуск. Один релиз в режиме «только метрики»: считать «would-block» без 429, затем включить enforcement и смотреть p95 задержки.
Токен-бакет против порогов соединений и сессий
Токен-бакет сглаживает короткие всплески HTTP: пополнение со скоростью r и запас B токенов. Потолок сессий или TCP/upstream-соединений ограничивает одновременные WebSocket, долгие агентские сессии и удержание памяти/подпроцессов. На практике нужны оба механизма: бакет на частоту запросов, семафор — на дорогую параллельную работу.
| Механизм | Когда уместен | Стартовая точка (подстройка под железо) |
|---|---|---|
| Токен-бакет (на арендатора) | Штормы webhook POST, опрос REST | Пополнение 5–20 rps, всплеск 30–60 токенов |
| Глобальный бакет | Общий upstream LLM / вендор API | Refill ≈ квота вендора с запасом |
| Лимит параллельных сессий | Долгие сессии агента, инструменты | 2–8 на класс узла; сумма по сетке ≤ потолок шлюза |
| Лимит соединений | Исчерпание файловых дескрипторов | Жёсткий потолок с запасом к ulimit -n |
CI и каналы сообщений: связка с конкурентностью шлюза
Лимиты на шлюзе бессмысленны, если пайплайны их игнорируют. В GitHub Actions задайте группы concurrency, чтобы в окружение не уходили десять deploy одновременно, и ограничьте параллелизм matrix, иначе каждый job откроет свою сессию. Для чат-автоматизации ограничьте повторы исходящих коннекторов и входящий fan-in webhook так же, как HTTP-клиентов: второй «токен-бакет» — на сообщения в минуту рядом с RPS. Если на узлах включён предпрогрев skills, ограничьте его конкурентность и разнесите по времени с merged health-пробами, чтобы холодный старт не совпадал с открытием сессий на шлюзе.
Проверки здоровья и автоматический сброс нагрузки
Свяжите лимитеры с состоянием здоровья: лёгкий /healthz с диском, пингом очереди и критичными зависимостями. При провале составного пробы или выходе p95 за SLO переключайте флаг: для новых сессий — 503 с Retry-After, для текущих — короткий drain. Опционально ужесточайте скорость пополнения токенов при CPU > 80% N секунд и ослабляйте после M минут стабильности. Балансировщик должен использовать ту же пробу, чтобы трафик ушёл с реплики до перегрева.
Наблюдение сбоев и поля логов
Оператору нужна одна схема JSON на все узлы. На каждый отклонённый или «сброшенный» запрос — одна строка с полями:
| Поле | Назначение |
|---|---|
mesh_node_id |
Какой Mac/VM открыл сессию (корреляция с метками CI) |
gateway_instance_id |
Pod, launchd label или hostname за VIP |
route_class |
interactive / ci_ingest / internal_worker |
limit_name |
Например tenant_rps, global_sessions |
client_id |
Отпечаток ключа API или subject (без секрета) |
http_status |
429 vs 503 — разные плейбуки on-call |
retry_after_ms |
Эхо для клиентского backoff |
queue_depth_hint |
Опционально: снимок брокера для хвоста очереди |
Алерты: устойчивый процент 429 по арендатору (часто misconfig), всплески 503 с падающим health (инцидент ёмкости). Трейсы помогут отделить «отсекли на краю» от «таймаут воркера».
FAQ
Где ставить rate limit — на reverse proxy или внутри OpenClaw?
На reverse proxy — грубые лимиты по IP и API key и TLS; в процессе шлюза — лимиты, зависящие от сессий OpenClaw, инструментов и маршрутизации. Документируйте оба слоя, чтобы ретраи не удваивали QPS.
Как узлы избегают «стадного эффекта»?
Идентичный конфиг лимитеров за LB, шардирование шлюзов по командам с Redis-квотами, джиттер для cron/CI и потолок воркеров на узел ≤ бюджет шлюза в сумме.
Какой статус отдавать клиенту?
429 при устойчивом rate limit с Retry-After; 503 при перегрузке или сбое зависимостей по health. Логируйте одинаково.
Кратко
Общий шлюз OpenClaw на MeshMac требует явных rate limit и потолка параллельных сессий, согласованных с CI и чатами. Сочетайте токен-бакет с капом соединений, при необходимости связывайте сброс с health-check и фиксируйте компактный набор полей в логах. Дополнительные материалы — в хабе OpenClaw и индексе блога.
Нужны узлы под мультиузловой OpenClaw?
Сравните тарифы и покупку MeshMac без обязательного входа, загляните в центр помощи по SSH, VNC и доступу, продолжите в блоге и на странице OpenClaw — там смежные гайды по очередям, webhook и health.