---
read_when:
    - Запуск или отладка процесса Gateway
    - Исследование механизма принудительного запуска в единственном экземпляре
summary: 'Защита от запуска нескольких экземпляров Gateway: блокировка файла и привязка WebSocket/HTTP'
title: Блокировка Gateway
x-i18n:
    generated_at: "2026-07-13T18:11:13Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 24
    provider: openai
    source_hash: f5ac6d42c437b481c68a23a0aa4c00aeac9131acd76f3516ce3e949f325e265b
    source_path: gateway/gateway-lock.md
    workflow: 16
---

## Зачем это нужно

- Только один процесс Gateway должен владеть каталогом состояния; дополнительные процессы Gateway следует запускать с изолированными профилями, каталогами состояния, конфигурациями и портами.
- Продолжать работу после сбоев/SIGKILL, не оставляя устаревших файлов блокировки.
- Немедленно завершать работу с понятной ошибкой, если порт уже занят другим процессом Gateway.

## Три уровня

При запуске владение проверяется в три этапа в следующем порядке:

1. **Блокировка владения состоянием** захватывает блокировку, привязанную к каноническому каталогу состояния. В ней участвуют все процессы Gateway, включая запущенные с `OPENCLAW_ALLOW_MULTI_GATEWAY=1`, поэтому деструктивное обслуживание SQLite не может выполняться одновременно с активным владельцем.
2. **Блокировка конфигурации** захватывает историческую блокировку для каждой конфигурации и записывает порт среды выполнения. В режиме нескольких процессов Gateway эта блокировка единственного экземпляра конфигурации пропускается, но блокировка владения состоянием сохраняется.
3. **Привязка сокета** привязывает обработчик HTTP/WebSocket (по умолчанию `ws://127.0.0.1:18789`) как эксклюзивный TCP-обработчик.

Каждый уровень может завершиться ошибкой независимо и генерирует собственное исключение `GatewayLockError`.

### Блокировки состояния и конфигурации

- Актуальность блокировки определяется записанным PID, идентификатором запуска процесса на платформе, если он доступен, и идентификатором процесса Gateway. Проверенный владелец остаётся полномочным во время запуска ещё до того, как его порт начнёт принимать подключения.
- Специализированный координатор SQLite последовательно выполняет проверку метаданных, освобождение блокировки устаревшего владельца и замену блокировки. Его эксклюзивная транзакция автоматически освобождается при сбое владеющего процесса.
- Если файл блокировки отсутствует или записанный процесс-владелец завершён, при запуске блокировка освобождается и процесс продолжает работу.
- Если любая из блокировок активно удерживается, при запуске попытки повторяются до 5 секунд (по умолчанию), после чего процесс прекращает работу:

  ```text
  GatewayLockError("Gateway уже запущен (pid <pid>); время ожидания блокировки истекло через <ms> мс")
  ```

### Привязка сокета

- При `EADDRINUSE` во время запуска выполняется до 20 повторных попыток привязки с интервалом 500 мс (всего около 10 секунд), чтобы переждать окно `TIME_WAIT` после недавно завершившегося процесса.
- Если после повторных попыток порт всё ещё используется:

  ```text
  GatewayLockError("другой экземпляр Gateway уже принимает подключения по адресу ws://127.0.0.1:<port>")
  ```

- Другие ошибки привязки:

  ```text
  GatewayLockError("не удалось привязать сокет Gateway по адресу ws://127.0.0.1:<port>: <cause>")
  ```

При завершении работы Gateway закрывает сервер HTTP/WebSocket и удаляет свои файлы
блокировки состояния и конфигурации.

## Примечания по эксплуатации

- Если порт занят другим процессом, не являющимся Gateway, ошибка будет такой же; освободите порт или выберите другой с помощью `openclaw gateway --port <port>`.
- `OPENCLAW_ALLOW_MULTI_GATEWAY=1` разрешает запуск нескольких экземпляров конфигурации/среды выполнения, но не совместное использование изменяемого состояния. Каждому экземпляру по-прежнему требуется уникальный `OPENCLAW_STATE_DIR`.
- При работе под управлением диспетчера служб новый процесс Gateway, столкнувшийся с любой из указанных выше ошибок, сначала проверяет `/healthz` существующего процесса. Если существующий процесс исправен, новый процесс оставляет управление за ним вместо завершения с ошибкой. В systemd он завершается с кодом `78`; параметр модуля `RestartPreventExitStatus=78` не позволяет `Restart=always` зациклиться при конфликте блокировки или `EADDRINUSE`. Если существующий процесс так и не становится исправным, число повторных проверок работоспособности ограничено по времени, после чего запуск завершается с указанной выше ошибкой блокировки вместо бесконечного цикла.
- Приложение macOS использует собственную упрощённую проверку PID перед запуском Gateway; фактическое ограничение во время выполнения обеспечивают описанные выше блокировка файла и привязка сокета.

## См. также

- [Несколько процессов Gateway](/ru/gateway/multiple-gateways) — запуск нескольких экземпляров с уникальными портами
- [Устранение неполадок](/ru/gateway/troubleshooting) — диагностика `EADDRINUSE` и конфликтов портов
