SystemdDoctor

Перезагрузка балансировщика рвёт соединения

Балансировщик умеет применять настройки без потери соединений: новый процесс принимает сокеты у старого, а старый доживает текущие запросы. Если вместо этого делается перезапуск, все соединения обрываются — и на нагруженном узле это заметно клиентам.

Вероятные причины

По порядку: сверху то, что встречается чаще.

  1. Вместо плавной перезагрузки делается перезапуск

    Перезапуск останавливает процесс и поднимает новый. Все установленные соединения обрываются.

  2. Сокеты не передаются новому процессу

    Без передачи сокетов новый процесс не может занять порт, пока старый его держит. Появляется окно отказов.

  3. Проверка настроек не выполняется до применения

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

Диагностика

Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.

Проверка настроек без применения.

sudo haproxy -c -f /etc/haproxy/haproxy.cfg

Как устроены перезагрузка и проверка перед запуском.

systemctl show haproxy -p ExecReload -p ExecStartPre

Что происходило при последней перезагрузке.

journalctl -u haproxy -n 30 --no-pager

Решение

Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.

1. Вместо плавной перезагрузки делается перезапуск
Почему происходит
Перезапуск останавливает процесс и поднимает новый. Все установленные соединения обрываются.
Как проверить
Посмотрите, что делает команда перезагрузки в unit-файле.
systemctl cat haproxy | grep -iE "ExecReload|ExecStart"
systemctl show haproxy -p ExecReload
Как исправить
Используйте плавную перезагрузку: новый процесс должен получить сокеты от старого. В штатных unit-файлах это уже настроено, ломается обычно при ручной правке.
2. Сокеты не передаются новому процессу
Почему происходит
Без передачи сокетов новый процесс не может занять порт, пока старый его держит. Появляется окно отказов.
Как проверить
Посмотрите настройку передачи сокетов.
sudo grep -iE "^\s*(stats socket|expose-fd)" /etc/haproxy/haproxy.cfg 2>/dev/null
sudo ss -tlnp | grep haproxy | head
Как исправить
Настройте передачу описателей через служебный сокет. Это условие работы плавной перезагрузки, а не необязательная тонкость.
3. Проверка настроек не выполняется до применения
Почему происходит
Ошибка в настройках при перезагрузке останавливает службу целиком, и узел выпадает из обслуживания.
Как проверить
Проверьте настройки и посмотрите команду до запуска.
sudo haproxy -c -f /etc/haproxy/haproxy.cfg 2>&1 | tail -5
systemctl show haproxy -p ExecStartPre
Как исправить
Добавьте проверку настроек предварительной командой: она отсечёт ошибку до остановки работающего процесса.
[Service]
ExecStartPre=/usr/sbin/haproxy -c -f /etc/haproxy/haproxy.cfg

Пример вывода

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

systemd[1]: Stopping haproxy.service - HAProxy Load Balancer...
haproxy[11600]: [WARNING] Stopping frontend main in 0 ms.
systemd[1]: Started haproxy.service - HAProxy Load Balancer.
haproxy[11610]: [ALERT] Starting frontend main: cannot bind socket [0.0.0.0:443]

Связанные ошибки

Где встречается чаще всего

Источники

  • Документация HAProxy: применение настроек документация программы
    сверено 15 сентября 2026
  • systemd.service(5)
    ExecReload= и ExecStartPre=.
    официальная документация, systemd 255
    сверено 15 сентября 2026
  • Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
    Воспроизведено перезапуском службы при установленных соединениях.
    собственная проверка, systemd 255
    сверено 15 сентября 2026