Выберите продукт

HAProxy: как разбирать 502, 503 и Layer4 connection problem

Когда HAProxy отдает 502 или 503, а в логах видны Layer4 connection problem и backend down, причина обычно не сводится к одному параметру. Этот runbook помогает по шагам проверить сеть, health checks, таймауты, TLS и реальное состояние backend.
HAProxy: как разбирать 502, 503 и Layer4 connection problem

Ошибки 502 и 503 в HAProxy для пользователя выглядят похоже: сайт не открывается, API отвечает нестабильно, мониторинг краснеет. Но для администратора это разные сценарии. Упрощенно: 503 чаще означает, что балансировщику некуда отправить запрос, а 502 — что соединение с backend формально было, но что-то пошло не так уже в процессе обмена.

Отдельно пугает сообщение Layer4 connection problem. Оно почти всегда указывает не на HTTP-уровень, а на TCP: соединение не установилось, было сброшено, не прошло по таймауту или заблокировано между узлами. Поэтому лечить такую ошибку только правкой маршрутов или заголовков обычно бесполезно.

Ниже — практический runbook, который помогает быстро локализовать причину. Он подходит для схем, где HAProxy стоит перед Nginx, Apache, Gunicorn, uWSGI, Node.js или любым TCP-сервисом.

Сначала определяем тип сбоя: 502 или 503

Первое правило — не менять конфиг наугад. Сначала нужно понять, в какой точке цепочки происходит отказ.

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

503 обычно появляется, когда у frontend нет ни одного доступного сервера в backend. Типовые причины такие:

  • все backend-серверы отмечены как DOWN по health checks;
  • приложение не поднялось после деплоя или рестарта;
  • ошибка в IP-адресе, порте или DNS-имени backend;
  • firewall или сетевые ACL режут доступ от HAProxy к приложению;
  • сервис слушает только 127.0.0.1, а HAProxy идет на другой адрес;
  • тип проверки не соответствует протоколу сервиса.

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

502 обычно связан не с полным отсутствием живых узлов, а с ошибкой во время запроса к backend. Например:

  • backend преждевременно закрыл соединение;
  • ответ пришел битый или неполный;
  • TLS до backend настроен неверно;
  • приложение не уложилось в timeout server;
  • TCP-соединение установилось, но HTTP-обмен сорвался.

Если клиенты видят 502, а в логах HAProxy одновременно есть признаки деградации backend, это часто плавающая проблема: часть соединений проходит, а часть отваливается на TCP или в начале ответа.

Смотрим, что HAProxy считает причиной

Главный источник правды — логи и статистика самого HAProxy. Без них очень легко лечить не причину, а последствия.

Начните с базовой проверки конфигурации и статуса процесса:

haproxy -c -f /etc/haproxy/haproxy.cfg
systemctl status haproxy
journalctl -u haproxy -n 100 --no-pager

Если конфиг валидный и процесс жив, переходите к логам запросов и событий health check:

journalctl -u haproxy -f
grep -i 'haproxy' /var/log/syslog | tail -n 100
grep -i 'Layer4 connection problem' /var/log/haproxy.log | tail -n 50

Ищите прежде всего такие признаки:

  • Layer4 connection problem, Connection refused, timeout, no server available;
  • какой backend и какой server уходит в DOWN;
  • падает один узел или сразу вся группа;
  • совпадает ли момент ошибки с релизом, рестартом приложения или сетевыми изменениями.

Подключаем статистический сокет

Если статистический сокет включен, диагностика заметно ускоряется. Через него видно состояние backend, счетчики ошибок и результаты проверок.

echo 'show stat' | socat stdio /run/haproxy/admin.sock
echo 'show info' | socat stdio /run/haproxy/admin.sock
echo 'show servers state' | socat stdio /run/haproxy/admin.sock

Когда backend массово уходит в DOWN, а причины похожи, проблема обычно общая: сеть, маршрут, firewall, DNS, неверный порт или единый сбой приложения после обновления.

Если балансировщик и backend разнесены по разным узлам, на отдельных VDS проще изолировать сетевые и ресурсные проблемы: быстрее понять, где именно теряются соединения и кто упирается в лимиты.

Что означает Layer4 connection problem на практике

Сообщение Layer4 connection problem относится к транспортному уровню. Это не «плохой HTTP», а ситуация, когда HAProxy не смог корректно установить или удержать TCP-соединение до backend.

Чаще всего за этим стоят:

  • Connection refused — на адресе и порту никто не слушает;
  • timeout connect — соединение не установилось вовремя;
  • сброс соединения через RST;
  • проблемы маршрутизации, ACL или firewall;
  • ошибка TLS-рукопожатия при работе с HTTPS backend.

Проверяем доступность backend вручную

Проверка должна выполняться именно с того хоста, где работает HAProxy. Иначе вы проверяете другой сетевой путь и можете сделать неверный вывод.

ss -ltnp | grep ':8080'
nc -vz 127.0.0.1 8080
nc -vz 10.0.0.12 8080
curl -I http://10.0.0.12:8080/
curl -vk https://10.0.0.12:8443/

Если nc или curl с узла HAProxy не проходят, причина уже близко: backend не слушает порт, слушает не на том IP или недоступен по сети.

Проверяем, слушает ли приложение правильный адрес

Очень частая ошибка после миграции или деплоя — приложение слушает только локальный интерфейс.

ss -ltnp | grep 8080

Если видно только 127.0.0.1:8080, а HAProxy идет на 10.0.0.12:8080, health checks закономерно начнут падать. Аналогичная история часто бывает с контейнерами, когда сервис запущен, но порт опубликован не туда.

Статистика HAProxy с состоянием backend-узлов в терминале

Health checks: полезны, но часто выбивают живые узлы

Проверки состояния в HAProxy спасают от отправки трафика на мертвый backend, но при неверной настройке сами становятся источником 503. Поэтому их надо проверять отдельно, а не считать заведомо правильными.

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

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

TCP-check и HTTP-check

Если backend — обычный HTTP-сервер, обычно лучше проверять именно HTTP-ответ, а не только факт открытия TCP-порта.

backend app
    option httpchk GET /health
    http-check expect status 200
    server app1 10.0.0.12:8080 check
    server app2 10.0.0.13:8080 check

Такой вариант хорош, если endpoint /health быстрый и действительно отражает готовность приложения. Плохая практика — проверять тяжелую страницу, которая зависит от базы, кэша и внешних API.

Если backend — чистый TCP-сервис, используйте TCP-check и не пытайтесь проверять его как HTTP:

backend tcp_app
    mode tcp
    option tcp-check
    server app1 10.0.0.12:3306 check
    server app2 10.0.0.13:3306 check

Проверьте URI, Host и ожидаемый код ответа

Типовой сценарий: backend отвечает на /health только при корректном Host или возвращает 301, 302 либо 403, а HAProxy ждет строго 200.

backend app
    option httpchk GET /health HTTP/1.1\r\nHost: app.internal
    http-check expect status 200
    server app1 10.0.0.12:8080 check

Если у вас маршрутизация завязана на виртуальные хосты, отсутствие правильного Host ломает проверку очень часто.

Не делайте health check слишком агрессивным

Слишком маленькие значения inter, fall и rise на проде вызывают флаппинг: сервер то UP, то DOWN. В результате краткая просадка превращается в лавину 503.

server app1 10.0.0.12:8080 check inter 3s fall 3 rise 2
server app2 10.0.0.13:8080 check inter 3s fall 3 rise 2

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

Если у вас уже используется HAProxy для более сложной логики трафика, полезно отдельно посмотреть и смежные механизмы, например stick tables и rate limiting в HAProxy, чтобы не спутать сетевую деградацию с последствиями ограничений на уровне балансировщика.

Таймауты: timeout connect, timeout server, timeout client

Неправильные таймауты — одна из самых частых и недооцененных причин нестабильной работы reverse proxy.

timeout connect

Этот параметр определяет, сколько HAProxy ждет установки соединения до backend. Если значение слишком маленькое, вы получите ложные Layer4 connection problem даже при кратковременных сетевых задержках.

defaults
    timeout connect 5s

Для локальной сети 5 секунд обычно достаточно. Если backend находится на удаленном узле, в overlay-сети или за VPN, ориентируйтесь на реальную латентность и пики нагрузки.

timeout server

Это максимальное время ожидания ответа от backend после установления соединения. Если приложение долго обрабатывает отчет, тяжелый SQL-запрос или ждет внешнюю систему, слишком маленький timeout server даст 502 и обрывы ответа.

defaults
    timeout server 30s

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

timeout client

Этот параметр задает, сколько HAProxy готов ждать клиента. Он не всегда напрямую связан с backend down, но влияет на общую картину, особенно при медленных клиентах, загрузках файлов и долгих соединениях.

defaults
    timeout client 30s

Если timeout client слишком короткий, в логах будет много шума, и клиентские обрывы легко принять за ошибки backend.

Частая ошибка — увеличить только один таймаут. На практике нужно сверять лимиты по всей цепочке: HAProxy, frontend-сервер, приложение и иногда даже upstream-сервисы.

Проверяем backend глубже: процесс, ресурсы и лимиты

Если HAProxy сообщает о проблеме с backend, это не значит, что виноват именно он. Очень часто балансировщик просто первым замечает деградацию приложения.

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

systemctl status nginx
systemctl status apache2
systemctl status php8.2-fpm
systemctl status gunicorn
journalctl -u nginx -n 100 --no-pager
journalctl -u php8.2-fpm -n 100 --no-pager

Обычно ищем такие признаки:

  • рестарты процессов;
  • ошибки bind на порт;
  • исчерпание воркеров;
  • OOM killer;
  • подвисание на старте после релиза;
  • переполненные очереди подключения.

Если сервис формально жив, но отвечает медленно, проверьте CPU, память, iowait и число соединений:

uptime
free -m
vmstat 1 5
top -b -n 1 | head -n 20
ss -s
ss -tan state established '( sport = :8080 or dport = :8080 )'

На перегруженном backend health checks начинают сыпаться первыми. После этого HAProxy помечает сервер как DOWN, и пользователь уже видит 503 как следствие, а не как первопричину.

Если сервисы разнесены по разным ролям, держать HAProxy и backend на отдельных VDS обычно удобнее и для диагностики, и для предсказуемой производительности: проще увидеть, где именно упираетесь в CPU, память или сеть.

Firewall, маршрутизация и сетевые ACL

Если backend жив, порт слушает, а timeout connect и Connection refused продолжаются, почти всегда нужно идти в сетевой слой. Особенно после миграции, переезда в приватную подсеть или изменения правил безопасности.

nft list ruleset
iptables -S
ss -ltnp
ip addr
ip route
ping -c 2 10.0.0.12
traceroute 10.0.0.12

Типовые сценарии здесь такие:

  • backend после обновления оказался в другой подсети;
  • security group разрешает внешний трафик, но не соединения от HAProxy;
  • локальный firewall на backend не пропускает внутренний порт;
  • маршрут через VPN поднялся не полностью;
  • локальные политики безопасности мешают сервису штатно принимать соединения.

Если сеть менялась недавно, полезно сравнить маршрут от HAProxy до backend и правила фильтрации по обе стороны соединения, а не только на одном узле.

Мониторинг серверов и диагностика сети при сбоях backend

TLS до backend: частая причина скрытых ошибок

Когда HAProxy проксирует трафик не на HTTP, а на HTTPS backend, добавляется еще один слой проблем: сертификат, SNI, версия TLS и проверка цепочки.

backend app_tls
    server app1 10.0.0.12:8443 ssl verify none check
    server app2 10.0.0.13:8443 ssl verify none check

Такой пример может подойти для диагностики, но на проде лучше явно понимать, нужен ли SNI, требуется ли проверка сертификата и какие параметры TLS поддерживает backend.

Проверить это с узла HAProxy можно так:

openssl s_client -connect 10.0.0.12:8443 -servername app.internal

Если рукопожатие зависит от имени хоста, проблема часто именно в SNI. А если до backend поднимается HTTPS с верификацией, стоит заранее привести в порядок и серверные SSL-сертификаты, чтобы не маскировать ошибки TLS параметром verify none.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Типовые ошибки конфигурации HAProxy

Неверный режим backend

Frontend работает в HTTP-режиме, а backend объявлен как TCP, либо наоборот. В результате логика маршрутизации и health checks не соответствует реальному протоколу.

Проверка не того порта

Приложение слушает 8080, а check идет на 8000. Или сервис уже переехал на Unix socket, а HAProxy продолжает стучаться по TCP.

DNS-имя backend обновилось, а HAProxy использует старый адрес

Если backend задается по имени, обязательно проверьте, как именно HAProxy резолвит адрес и когда перечитывает DNS. После смены записи можно долго ходить в устаревший IP.

Неподходящий endpoint для health check

Если endpoint зависит от базы, Redis, очередей и внешних API, то проверка измеряет не готовность веб-сервера, а состояние всей системы целиком. Иногда это нужно, но чаще приводит к ложным отключениям узлов.

Минимальный порядок диагностики, который экономит время

  1. Определить, ошибка больше похожа на 502 или на 503.
  2. Посмотреть логи HAProxy и найти точную формулировку причины.
  3. Убедиться, что backend слушает нужный IP и порт.
  4. С узла HAProxy выполнить nc и curl к backend.
  5. Проверить состояние health checks и флаппинг серверов.
  6. Сверить timeout connect, timeout server и timeout client между всеми звеньями.
  7. Проверить firewall, маршруты и сетевые ACL.
  8. Если используется HTTPS до backend — отдельно проверить TLS и SNI.
  9. На backend посмотреть ресурсы, логи приложений и рестарты процессов.

Пример аккуратного базового конфига

Это не универсальный шаблон, а безопасная отправная точка для типового HTTP backend:

global
    log /dev/log local0
    stats socket /run/haproxy/admin.sock mode 660 level admin

defaults
    mode http
    log global
    option httplog
    timeout connect 5s
    timeout client 30s
    timeout server 30s

frontend fe_http
    bind :80
    default_backend be_app

backend be_app
    option httpchk GET /health
    http-check expect status 200
    server app1 10.0.0.12:8080 check inter 3s fall 3 rise 2
    server app2 10.0.0.13:8080 check inter 3s fall 3 rise 2

Если даже с такой базой backend регулярно уходит в DOWN, проблема почти всегда уже не в «магии HAProxy», а в сети, приложении, таймаутах или инфраструктуре вокруг него.

Если у вас смешанная среда с Kubernetes, ingress и отдельными reverse proxy, полезно также сверить поведение балансировщика с типовой схемой ingress в k3s и HAProxy: часть ошибок там проявляется похожим образом, хотя причина лежит выше по стеку.

Вывод

Ошибки 502, 503 и сообщение Layer4 connection problem редко лечатся одной случайной правкой конфига. Важно разделять уровни: доступность TCP, корректность health checks, согласованность таймаутов, состояние приложения и сетевой путь между узлами.

Рабочая схема простая: сначала порт и сеть, потом checks, потом таймауты, потом приложение. Если идти именно в таком порядке, причина находится заметно быстрее, а HAProxy из источника тревожных сообщений превращается в удобную точку наблюдения за всей цепочкой.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: как исправить libc6 и libstdc++ version mismatch без поломки системы OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить libc6 и libstdc++ version mismatch без поломки системы

Ошибки GLIBCXX not found, GLIBC not found и libc6 version mismatch обычно появляются после ручной установки пакетов, копирования б ...
Как расширить диск и файловую систему на Debian/Ubuntu после увеличения VDS OpenAI Статья написана AI (GPT 5)

Как расширить диск и файловую систему на Debian/Ubuntu после увеличения VDS

Если после увеличения диска VDS Debian или Ubuntu всё ещё показывает старый размер, проблема обычно не в гипервизоре, а в разделе ...
Linux swappiness, vfs_cache_pressure и dirty_ratio: практический тюнинг памяти и writeback OpenAI Статья написана AI (GPT 5)

Linux swappiness, vfs_cache_pressure и dirty_ratio: практический тюнинг памяти и writeback

Параметры VM в Linux часто меняют наугад: снижают swappiness, трогают vfs_cache_pressure и dirty_ratio, а потом получают фризы, вс ...