Как volrix.pm работает несколькими процессами и серверами: ведущий планировщик, лицензия в базе, ответ 503 при переключении БД, копии pgBackRest.
Обновлено 16.10.2026
С версии 0.112.0 volrix.pm работает несколькими процессами backend на одном сервере и несколькими серверами на одной базе. Все, что раньше жило в памяти одного процесса, стало общим, а фоновые задачи выполняет один ведущий планировщик. Здесь - что из этого следует для администратора: как добавить процессы, как понять, кто ведущий, что видят пользователи при переключении базы и как устроены копии в кластере.
Состояние серверов и процессов: «Администрирование» → «Наблюдение» → «Кластер» - см. Кластер.
В установке на один сервер работают контейнеры volrix-postgres, volrix-backend, volrix-scheduler и volrix-frontend. Число процессов внутри volrix-backend задает переменная WEB_WORKERS в файле .env каталога установки: по умолчанию 1, ориентир - число ядер процессора. Каждый процесс занимает свою память, поэтому добавляйте процессы, когда процессор нагружен запросами пользователей, а памяти хватает.
# в .env каталога установки (/opt/volrix при установке мастером, ~/volrix без мастера) WEB_WORKERS=4 # применить cd /opt/volrix docker compose -f docker-compose.release.yml up -d backend
Проверка: на экране «Кластер» в карточке сервера появится «процессов: 4». Значение меньше 1 backend не примет и не запустится («WEB_WORKERS must be at least 1» в docker logs volrix-backend).
Планировщик в такой установке работает в отдельном контейнере volrix-scheduler, а в volrix-backend он выключен (RUN_SCHEDULER: "false" в docker-compose.release.yml). Менять это не нужно: процессы backend обслуживают запросы, фоновые задачи идут один раз.
В кластере на каждом узле приложения работают volrix-backend (по умолчанию 2 процесса, параметр workers в разделе app файла volrix-cluster.yml), volrix-web и volrix-pgproxy. Отдельного контейнера планировщика там нет: он включен в backend на каждом узле.
Планировщик может быть включен в нескольких процессах и на нескольких серверах, но задачи выполняет один - ведущий. Остальные в резерве и раз в 5 секунд проверяют, не освободилось ли место. Ведущий раз в 5 секунд проверяет связь с базой; если она пропала (сбой сети, переключение основного сервера БД), он сразу останавливает задачи, и ведущим становится другой процесс. Прерванный перенос файлов между хранилищами тоже продолжает только ведущий.
Ведущий раз в минуту публикует время следующих запусков - его показывает экран Расписание задач из любого процесса, - и раз в 20 секунд собирает данные для экрана «Кластер». Там узел с ведущим отмечен значком «планировщик».
# один сервер docker logs --since 1h volrix-scheduler 2>&1 | grep Планировщик # кластер: на узле приложения docker logs --since 1h volrix-backend 2>&1 | grep Планировщик
Текст лицензии хранится в базе данных, а файл data/volrix.lic - его локальная копия. Поэтому лицензию видят все процессы и серверы, и она восстанавливается вместе с дампом базы. Загрузка на экране «Лицензия» записывает лицензию в базу и в файл и сразу действует во всех процессах.
Файл, положенный на сервер вручную, сверяется с базой только при запуске backend: если он изменен позже записи в базе, он попадает в базу и в остальные процессы; если раньше - переписывается лицензией из базы. Подробнее - Лицензия.
В кластере при отказе основного сервера PostgreSQL Patroni делает основным синхронную реплику, а приложение само подключается к новому серверу. На проверочных стендах запись прерывалась на 23-31 секунду, подтвержденные записи не терялись.
Запросы, попавшие на переключение, получают ответ 503 с текстом «База данных переключается на резервный сервер. Повторите через несколько секунд.» и заголовком Retry-After: 5 - вместо «Внутренняя ошибка сервера». Пользователь видит это сообщение и повторяет действие. В журнал ошибок такие ответы не попадают, в журнале volrix-backend остается предупреждение «База недоступна: метод адрес - тип ошибки».
Тот же ответ бывает и на одном сервере, когда база недоступна несколько секунд: перезапуск volrix-postgres или нет свободных соединений с базой. Ошибки самих данных (дубликат, нарушение связи между записями) так не помечаются.
В кластере копии снимает pgBackRest на серверах БД. Хранилище и время выбираются на шаге мастера «Резервные копии»: S3 (SeaweedFS или хранилище организации) или общий для серверов БД каталог (NFS), «Время копии» (по умолчанию 02:30), «Хранить полных копий» (по умолчанию 2). Вариант «Пока без резервных копий» оставляет кластер без копий pgBackRest.
# состояние копий - на любом сервере БД sudo docker exec volrix-patroni pgbackrest --stanza=volrix info # полная копия сейчас - на основном сервере БД # (на реплике команда ответит «Узел не основной сервер - копию снимает другой») sudo volrix-backup full
Экран Резервные копии в кластере тоже работает, но его дамп ложится в каталог /var/lib/volrix/backups того узла приложения, где выполнялся: ночной - на узле ведущего планировщика, ручной - на узле, который обработал запрос. Каталоги узлов не общие, поэтому список на экране зависит от того, на какой узел попал запрос. Основной механизм копий кластера - pgBackRest.
Кроме копий базы сохраните в надежном месте файл секретов кластера /opt/volrix-installer/work/volrix-cluster.secrets.yml на первом сервере: в нем SECRET_KEY и пароли. Без исходного SECRET_KEY зашифрованные в базе пароли интеграций и секреты двухфакторного входа не расшифровать.
Восстановление кластера целиком (порча данных, ошибочное удаление) выполняется из консоли: остановить приложение и Patroni на всех серверах, восстановить копию pgBackRest на одном сервере (при необходимости - на момент времени), запустить на нем Patroni, затем на остальных - они станут репликами, затем приложение. Встроенного сценария для этого пока нет, поэтому планируйте восстановление вместе с поддержкой volrix.pm.
Схема серверов, роли PostgreSQL, кворум etcd и предупреждения
Дамп на одном сервере, восстановление и копии в кластере
Время ночных и утренних фоновых задач