Супервизия
Супервизор управляет жизненным циклом сервисов: порядком запуска, автоматическими перезапусками и корректным завершением. Сервисы с 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_start |
false |
Запускать автоматически при старте супервизора |
start_timeout |
10s |
Максимальное время на запуск |
stop_timeout |
10s |
Максимальное время на корректное завершение |
stable_threshold |
5s |
Время работы до признания сервиса стабильным |
depends_on |
[] |
Сервисы, которые должны быть запущены первыми |
Разрешение зависимостей
Супервизор определяет зависимости из двух источников:
- Явные зависимости, объявленные в
depends_on - Зависимости из реестра, извлечённые из ссылок записей (например,
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%) |
|---|---|---|
| 1 | 1s | 0.9s - 1.1s |
| 2 | 2s | 1.8s - 2.2s |
| 3 | 4s | 3.6s - 4.4s |
| 4 | 8s | 7.2s - 8.8s |
| ... | ... | ... |
| N | 90s | 81s - 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
См. также
- Модель процессов — жизненный цикл процессов
- Конфигурация — формат YAML
- Модуль Security — проверка разрешений в Lua