Перезагрузка балансировщика рвёт соединения
Балансировщик умеет применять настройки без потери соединений: новый процесс принимает сокеты у старого, а старый доживает текущие запросы. Если вместо этого делается перезапуск, все соединения обрываются — и на нагруженном узле это заметно клиентам.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Вместо плавной перезагрузки делается перезапуск
Перезапуск останавливает процесс и поднимает новый. Все установленные соединения обрываются.
-
Сокеты не передаются новому процессу
Без передачи сокетов новый процесс не может занять порт, пока старый его держит. Появляется окно отказов.
-
Проверка настроек не выполняется до применения
Ошибка в настройках при перезагрузке останавливает службу целиком, и узел выпадает из обслуживания.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Проверка настроек без применения.
sudo haproxy -c -f /etc/haproxy/haproxy.cfgКак устроены перезагрузка и проверка перед запуском.
systemctl show haproxy -p ExecReload -p ExecStartPreЧто происходило при последней перезагрузке.
journalctl -u haproxy -n 30 --no-pagerРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Перезапуск останавливает процесс и поднимает новый. Все установленные соединения обрываются.
- Как проверить
-
Посмотрите, что делает команда перезагрузки в unit-файле.
systemctl cat haproxy | grep -iE "ExecReload|ExecStart" systemctl show haproxy -p ExecReload
- Как исправить
- Используйте плавную перезагрузку: новый процесс должен получить сокеты от старого. В штатных unit-файлах это уже настроено, ломается обычно при ручной правке.
- Почему происходит
- Без передачи сокетов новый процесс не может занять порт, пока старый его держит. Появляется окно отказов.
- Как проверить
-
Посмотрите настройку передачи сокетов.
sudo grep -iE "^\s*(stats socket|expose-fd)" /etc/haproxy/haproxy.cfg 2>/dev/null sudo ss -tlnp | grep haproxy | head
- Как исправить
- Настройте передачу описателей через служебный сокет. Это условие работы плавной перезагрузки, а не необязательная тонкость.
- Почему происходит
- Ошибка в настройках при перезагрузке останавливает службу целиком, и узел выпадает из обслуживания.
- Как проверить
-
Проверьте настройки и посмотрите команду до запуска.
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: cannot bind socket и плавающий адрес HAProxy не запускается на пассивном узле кластера: адрес не поднят. Параметр ip_nonlocal_bind.
- Address already in use при запуске службы Порт или адрес уже занят: bind() failed (98: Address already in use). Как найти владельца порта и что делать с остатками прежнего процесса.
- nginx reload не применяет изменения Перезагрузка nginx прошла, а изменения не действуют: правка не в том файле, файл не включён, кеш, старые рабочие процессы.
- Оповещения не уходят: настройки не перечитались Правка настроек оповещений не применилась: перезагрузка отказала, а служба продолжает работать с прежними.
- Apache: Invalid command — не включён модуль Apache не запускается: директива требует модуль, который не подключён. Как найти нужный модуль и включить.
- Apache: could not bind to address Apache не занимает порт: конфликт с nginx, порт занят, нет прав на привилегированный порт.
- Apache: конфликт модулей многопроцессности и PHP Apache не запускается после включения модуля PHP: несовместимость с выбранным модулем многопроцессности.
- Apache: правила .htaccess не действуют Файл .htaccess игнорируется: запрещён параметром AllowOverride, нет нужного модуля, файл не читается.
Где встречается чаще всего
Источники
- Документация HAProxy: применение настроек
-
systemd.service(5)
ExecReload= и ExecStartPre=. -
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено перезапуском службы при установленных соединениях.