Перейти к содержимому

Супервизия

Супервизор управляет жизненным циклом сервисов: порядком запуска, автоматическими перезапусками и корректным завершением. Сервисы с auto_start: true запускаются при старте приложения.

Сервисы регистрируются в супервизоре через блок lifecycle. Для процессов используйте process.service как обёртку над определением процесса:

# Определение процесса (код)
- name: worker_process
kind: process.lua
source: file://worker.lua
method: main
# Супервизируемый сервис (обёртка процесса с управлением жизненным циклом)
- name: worker
kind: process.service
process: app:worker_process
host: app:processes
lifecycle:
auto_start: true
start_timeout: 30s
stop_timeout: 10s
stable_threshold: 5s
depends_on:
- app:database
restart:
initial_delay: 2s
max_delay: 60s
max_attempts: 10
ПолеПо умолчаниюОписание
auto_startfalseЗапускать автоматически при старте супервизора
start_timeout10sМаксимальное время на запуск
stop_timeout10sМаксимальное время на корректное завершение
stable_threshold5sВремя работы до признания сервиса стабильным
depends_on[]Сервисы, которые должны быть запущены первыми

Супервизор определяет зависимости из двух источников:

  1. Явные зависимости, объявленные в depends_on
  2. Зависимости из реестра, извлечённые из ссылок записей (например, database: app:db в конфиге)
graph LR
A[HTTP Server] --> B[Router]
B --> C[Handler Function]
C --> D[Database]
C --> E[Cache]

Зависимости запускаются раньше зависимых. Если сервис C зависит от A и B, оба должны перейти в состояние Running перед запуском C.

Не нужно объявлять инфраструктурные записи вроде баз данных в depends_on. Супервизор автоматически извлекает зависимости из ссылок реестра в конфигурации записи.

При сбое сервиса супервизор повторяет попытки с экспоненциальной задержкой:

lifecycle:
restart:
initial_delay: 1s # Ожидание первой попытки
max_delay: 90s # Максимальная задержка
backoff_factor: 2.0 # Множитель задержки за попытку
jitter: 0.1 # ±10% рандомизация
max_attempts: 0 # 0 = бесконечные попытки
ПопыткаБазовая задержкаС jitter (±10%)
11s0.9s - 1.1s
22s1.8s - 2.2s
34s3.6s - 4.4s
48s7.2s - 8.8s
N90s81s - 99s (ограничено)

Когда сервис работает дольше stable_threshold, счётчик попыток сбрасывается. Это предотвращает постоянную эскалацию задержек из-за временных сбоев.

Эти ошибки прекращают попытки перезапуска:

  • Отмена контекста
  • Явный запрос на завершение
  • Ошибки, помеченные как не подлежащие повтору

Сервисы могут работать с определённой идентичностью:

# Определение процесса
- name: admin_worker_process
kind: process.lua
source: file://admin_worker.lua
method: main
# Супервизируемый сервис с контекстом безопасности
- name: admin_worker
kind: process.service
process: app:admin_worker_process
host: app:processes
lifecycle:
auto_start: true
security:
actor:
id: "service:admin-worker"
meta:
role: admin
groups:
- app:admin_policies
policies:
- app:data_access

Контекст безопасности задаёт:

ПолеОписание
actor.idСтрока идентичности сервиса
actor.metaМетаданные ключ-значение (роль, разрешения и т.д.)
groupsГруппы политик для применения
policiesОтдельные политики для применения

Код, выполняющийся в сервисе, наследует этот контекст безопасности. Модуль security может проверять разрешения:

local security = require("security")
if security.can("delete", "users") then
-- разрешено
end
Без настроенного контекста безопасности сервис работает без актора. В строгом режиме (по умолчанию) проверки безопасности будут отклонены. Настройте контекст безопасности для сервисов, которым нужна авторизация.
stateDiagram-v2
[*] --> Inactive
Inactive --> Starting
Starting --> Running
Running --> Stopping
Stopping --> Stopped
Stopped --> [*]
Running --> Failed
Starting --> Failed
Failed --> Starting : retry

Супервизор переводит сервисы через эти состояния:

СостояниеОписание
InactiveЗарегистрирован, но не запущен
StartingИдёт запуск
RunningРаботает нормально
StoppingИдёт корректное завершение
StoppedЧисто завершён
FailedПроизошла ошибка, возможен повтор

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

Остановка: сначала зависимые, потом зависимости. Это гарантирует, что зависимые сервисы завершатся до остановки их зависимостей.

Запуск: database → cache → handler → http_server
Остановка: http_server → handler → cache → database