// Engineering Log

Прокси-серверы: Часть 3 — HAProxy

Опубликовано 21.09.2026

HAProxy (High Availability Proxy) — балансировщик нагрузки и обратный прокси для TCP и HTTP с открытым исходным кодом. В отличие от nginx, HAProxy не раздаёт файлы и не выполняет код приложений: его задача — принимать соединения, распределять их между серверами, следить за состоянием серверов и применять к трафику правила. Помимо свободной версии компания HAProxy Technologies выпускает коммерческую HAProxy Enterprise.

Ветки с чётным номером имеют долгосрочную поддержку (LTS) в течение пяти лет. На сентябрь 2026 года актуальны LTS-ветки 3.2 (выпущена в мае 2025 года) и 3.4 (июнь 2026 года). Для рабочих серверов стоит брать LTS-версию из репозитория дистрибутива или из официальных пакетов для него.

Основные понятия конфигурации

Конфигурация хранится в /etc/haproxy/haproxy.cfg и состоит из секций:

  • global — параметры процесса: журналирование, пользователь, лимит соединений;
  • defaults — значения по умолчанию для остальных секций: режим, таймауты;
  • frontend — где HAProxy принимает соединения: адрес, порт, сертификат, правила;
  • backend — группа серверов, алгоритм балансировки и проверки состояния;
  • listen — сокращённая запись, объединяющая frontend и backend.

Режим работы задаётся директивой mode: http — HAProxy разбирает HTTP-запросы и может принимать решения по пути, заголовкам и cookie; tcp — передаёт соединение целиком, не заглядывая внутрь, что подходит для любых протоколов поверх TCP.

Пример: HTTPS-сайт на трёх серверах

haproxy
global
    log /dev/log local0
    maxconn 20000
    user haproxy
    group haproxy

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

frontend web
    bind :80
    bind :443 ssl crt /etc/haproxy/certs/example.ru.pem alpn h2,http/1.1
    http-request redirect scheme https unless { ssl_fc }
    http-request set-header X-Forwarded-Proto https if { ssl_fc }
    option forwardfor
    default_backend app

backend app
    balance roundrobin
    option httpchk
    http-check send meth GET uri /health ver HTTP/1.1 hdr Host example.ru
    http-check expect status 200
    server app1 10.0.0.11:3000 check inter 3s fall 3 rise 2
    server app2 10.0.0.12:3000 check inter 3s fall 3 rise 2
    server app3 10.0.0.13:3000 check inter 3s fall 3 rise 2 backup

Разбор:

  • в файле example.ru.pem сертификат, промежуточные сертификаты и закрытый ключ хранятся вместе, одним файлом;
  • alpn h2,http/1.1 включает HTTP/2 для клиентов;
  • option forwardfor добавляет заголовок X-Forwarded-For с адресом клиента;
  • timeout tunnel 1h задаёт время жизни соединений после перехода на WebSocket; без неё они закрывались бы по timeout client и timeout server;
  • balance roundrobin отправляет запросы по очереди. Другие варианты: leastconn — на сервер с наименьшим числом соединений (подходит для долгих соединений), source — один клиентский IP всегда на один сервер.

Проверка и применение конфигурации:

bash
haproxy -c -f /etc/haproxy/haproxy.cfg && systemctl reload haproxy

Проверки состояния серверов

Главное отличие HAProxy от бесплатного nginx — активные проверки: HAProxy сам периодически обращается к каждому серверу и не ждёт, пока на неработающий сервер попадут запросы пользователей. В примере выше каждые 3 секунды отправляется запрос GET /health. После трёх неудачных проверок подряд (fall 3) сервер исключается из балансировки, после двух успешных (rise 2) возвращается. Сервер с пометкой backup получает трафик, только когда основные серверы недоступны.

Виды проверок:

  • TCP — только установка соединения; включается словом check без option httpchk;
  • HTTP — запрос к адресу проверки с ожидаемым кодом ответа или содержимым;
  • проверки протоколов — встроенные для MySQL, PostgreSQL, Redis, SMTP, LDAP и приветствия TLS;
  • агент — на сервере работает небольшая программа, которая сообщает HAProxy свою загрузку или просит временно снять сервер с балансировки.

Проверки по ICMP (ping) в HAProxy нет, да она и не показала бы, работает ли приложение. Полезнее всего HTTP-проверка отдельного адреса /health, который приложение обслуживает только при доступной базе данных и других зависимостях.

Привязка пользователя к серверу

Если приложение хранит сессию в памяти процесса, пользователь должен попадать на один и тот же сервер. HAProxy может сам выдавать cookie с именем сервера:

haproxy
backend app
    balance roundrobin
    cookie SERVERID insert indirect nocache
    server app1 10.0.0.11:3000 check cookie app1
    server app2 10.0.0.12:3000 check cookie app2

Если сервер станет недоступен, пользователь будет перенаправлен на другой и потеряет сессию. Надёжнее хранить сессии в общем хранилище и не привязывать пользователей к серверам.

Ограничение частоты запросов: stick-tables

Stick-table — таблица в памяти HAProxy, в которой хранятся счётчики по ключу, например по IP-адресу клиента. На её основе строятся ограничения частоты:

haproxy
frontend web
    bind :443 ssl crt /etc/haproxy/certs/example.ru.pem alpn h2,http/1.1
    stick-table type ipv6 size 1m expire 10m store http_req_rate(10s)
    http-request track-sc0 src
    http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
    default_backend app

Клиент, отправивший больше 100 запросов за 10 секунд, получает ответ 429. Тип ipv6 хранит и IPv4-адреса. Эти же таблицы используют для учёта ошибок по клиентам, ограничения числа одновременных соединений и обмена счётчиками между двумя экземплярами HAProxy (секция peers).

TCP-режим: балансировка PostgreSQL

haproxy
frontend postgres
    mode tcp
    bind :5432
    default_backend pg_servers

backend pg_servers
    mode tcp
    balance leastconn
    option pgsql-check user haproxy
    server pg1 10.0.0.21:5432 check
    server pg2 10.0.0.22:5432 check backup

option pgsql-check проверяет, что PostgreSQL отвечает на подключение пользователя haproxy (он должен существовать в базе). HAProxy не знает, какой из серверов сейчас основной, а какой — реплика только для чтения. В кластерах с автоматическим переключением, например Patroni, проверку направляют на HTTP-интерфейс Patroni, который отвечает кодом 200 только на основном сервере.

Страница статистики

haproxy
frontend stats
    mode http
    bind 127.0.0.1:8404
    stats enable
    stats uri /stats
    stats refresh 10s
    stats auth admin:надёжный-пароль

На странице видны состояние каждого сервера, число соединений, ошибки и время ответа. Страницу не стоит открывать в интернет: в примере она слушает только локальный адрес и доступна через SSH-туннель. Для систем мониторинга HAProxy отдаёт метрики в формате Prometheus (http-request use-service prometheus-exporter).

Кеширование

У HAProxy есть кеш ответов в памяти. Он рассчитан на небольшие часто запрашиваемые объекты, например ответы API: общий объём ограничен 4095 МБ, а размер одного объекта — половиной этого объёма. Для кеширования крупных файлов и страниц с большим объёмом данных лучше подходит nginx с кешем на диске, поэтому их часто используют вместе.

Отказоустойчивость самого HAProxy

Балансировщик устраняет единую точку отказа среди серверов приложения, но сам становится такой точкой. Обычно ставят два HAProxy с одинаковой конфигурацией и общим виртуальным IP-адресом, который переносит keepalived (протокол VRRP): если основной узел перестаёт отвечать, адрес за секунды переходит на резервный.

Управление без перезапуска

Через сокет управления (Runtime API) можно смотреть состояние и выводить серверы из работы, не меняя конфигурацию. В секцию global добавляют:

haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin

После этого, например, перед обновлением сервера его переводят в режим обслуживания, а потом возвращают:

bash
echo "set server app/app1 state maint" | socat stdio /run/haproxy/admin.sock
echo "set server app/app1 state ready" | socat stdio /run/haproxy/admin.sock
echo "show stat" | socat stdio /run/haproxy/admin.sock

В режиме обслуживания HAProxy не отправляет на сервер новые запросы. Так приложение обновляют по одному серверу без простоя для пользователей.

Журналы

HAProxy пишет журнал через syslog. С option httplog каждая строка содержит адрес клиента, выбранные frontend, backend и сервер, код ответа, размер ответа и тайминги: сколько запрос ждал в очереди, сколько устанавливалось соединение с сервером и сколько сервер готовил ответ. По этим полям удобно искать, где именно возникает задержка, — в сети, в очереди или в самом приложении.

Сильные и слабые стороны

Достоинства:

  • активные проверки состояния серверов в свободной версии;
  • работа как с HTTP, так и с любым TCP-трафиком;
  • подробная статистика и метрики;
  • stick-tables для ограничений и учёта клиентов;
  • изменение состояния серверов на лету через Runtime API (сокет управления) без перезапуска.

Недостатки:

  • не раздаёт статические файлы и не запускает приложения;
  • кеш ограничен небольшими объектами в памяти;
  • синтаксис конфигурации и логика правил требуют времени на освоение.

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

// Contact

Нужна помощь?

Свяжись со мной и я помогу решить проблему

Написать в Telegram

Отвечаю в течение рабочего дня (03:00–13:00 GMT)

Или оставьте заявку здесь:

Подтвердите, что вы не бот.

Написать и получить быстрый ответ