Главная / База знаний / HAProxy: балансировка нагрузки и когда он лучше nginx
инструкция · 8 ноября 2026

HAProxy: балансировка нагрузки и когда он лучше nginx

Разбираем конфигурацию HAProxy для балансировки нагрузки: frontend, backend и ACL, алгоритмы распределения и health checks, а также честное сравнение с nginx в задачах балансировки.

HAProxy: специализированный инструмент, а не универсальный веб-сервер

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

Эта узкая специализация — не недостаток, а сознательный архитектурный выбор: вся кодовая база и внутренняя модель обработки соединений HAProxy оптимизированы исключительно под задачу балансировки, что даёт заметно более широкий и глубоко проработанный набор возможностей именно в этой области — сложные схемы health checks, гибкие ACL для маршрутизации на основе практически любого параметра запроса, stick tables для хранения состояния клиентов прямо в памяти балансировщика, детальная встроенная статистика по каждому бэкенду.

Типичное практическое применение HAProxy — точка входа перед несколькими серверами приложения (каждый из которых может сам по себе работать под управлением nginx или Apache), распределяющая трафик между ними, отслеживающая их состояние и исключающая из ротации те серверы, что перестали отвечать корректно. Эта статья разбирает базовую структуру конфигурации HAProxy, основные алгоритмы балансировки и health checks, а также разбирает честно, в каких сценариях набор возможностей HAProxy реально оправдывает выбор в его пользу вместо более привычной балансировки через nginx.

Структура конфигурации: frontend, backend и listen

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

Минимальная рабочая конфигурация: приём HTTP-трафика и распределение между тремя серверами
global
    log /dev/log local0
    maxconn 4096

defaults
    mode http
    timeout connect 5s
    timeout client 30s
    timeout server 30s

frontend web_front
    bind *:80
    default_backend web_servers

backend web_servers
    balance roundrobin
    server web1 10.0.0.11:80 check
    server web2 10.0.0.12:80 check
    server web3 10.0.0.13:80 check

Секция global задаёт общесистемные параметры процесса HAProxy (логирование, лимиты на число одновременных соединений), а defaults — значения по умолчанию для всех последующих frontend и backend блоков, которые можно переопределить в конкретном блоке при необходимости. Директива mode http включает обработку на уровне L7 с пониманием HTTP-протокола (заголовки, методы, коды состояния), тогда как mode tcp работает на уровне L4, просто передавая байты TCP-соединения без разбора содержимого — выбор режима определяется тем, нужна ли балансировщику логика, зависящая от содержимого HTTP-запроса, или достаточно распределения на уровне TCP-соединений.

Ключевое слово check в конце строки server включает активную проверку доступности этого сервера — без него HAProxy будет считать сервер всегда доступным и продолжит направлять на него трафик, даже если сервер фактически не отвечает, что делает check фактически обязательной практикой для любой конфигурации, претендующей на реальную отказоустойчивость.

ACL: маршрутизация на основе содержимого запроса

ACL (Access Control List) в терминологии HAProxy — не список доступа в привычном смысле файрвола, а именованное условие, проверяющее произвольный параметр запроса (путь URL, заголовок, домен, метод, cookie), которое затем используется в правилах маршрутизации для направления запроса на тот или иной backend.

Маршрутизация разных типов запросов на разные пулы серверов на основе пути URL
frontend web_front
    bind *:80
    acl is_api path_beg /api/
    acl is_static path_end .css .js .png .jpg .svg
    use_backend api_servers if is_api
    use_backend static_servers if is_static
    default_backend app_servers

В этом примере запросы, начинающиеся с /api/, направляются в отдельный пул серверов, обслуживающих API, запросы к файлам с расширениями статики — в отдельный пул, оптимизированный под отдачу статических файлов, а всё остальное попадает в backend по умолчанию, обслуживающий основное приложение. Такая маршрутизация на основе содержимого запроса — типичный пример возможности, для которой в nginx потребовались бы отдельные блоки location с похожей логикой, но у HAProxy условия ACL можно свободно комбинировать логическими операторами и переиспользовать в разных правилах без дублирования условия целиком.

Комбинирование нескольких условий ACL с отрицанием для более сложной маршрутизации
acl is_mobile hdr_sub(User-Agent) -i mobile
acl is_internal src 10.0.0.0/8
use_backend mobile_servers if is_mobile !is_internal

Health checks: активная и пассивная проверка бэкендов

Простейшая форма проверки доступности сервера в HAProxy — TCP health check, устанавливающий тестовое соединение с указанным портом сервера и считающий его доступным, если соединение успешно устанавливается, — этого достаточно для базового контроля того, что процесс на сервере вообще жив и слушает нужный порт, но не гарантирует, что приложение внутри действительно способно корректно обработать реальный запрос.

HTTP health check с проверкой конкретного эндпоинта и ожидаемого кода ответа
backend web_servers
    option httpchk GET /health
    http-check expect status 200
    server web1 10.0.0.11:80 check inter 3s fall 3 rise 2
    server web2 10.0.0.12:80 check inter 3s fall 3 rise 2

Директива option httpchk включает HTTP-level проверку — HAProxy отправляет реальный HTTP-запрос к указанному пути (в примере — /health, специальный эндпоинт приложения, отвечающий быстро и без обращения к тяжёлым внешним зависимостям) и, при указании http-check expect, проверяет не только сам факт ответа, но и конкретный код состояния или содержимое ответа. Такая проверка ловит ситуации, недоступные обычному TCP-чеку: например, процесс приложения жив и порт открыт, но сама логика приложения вернула ошибку 500 из-за потерянного соединения с базой данных.

Параметры inter, fall и rise настраивают чувствительность проверки: inter задаёт интервал между последовательными проверками, fall — сколько подряд неудачных проверок нужно, прежде чем сервер будет помечен как недоступный и исключён из ротации, а rise — сколько подряд успешных проверок требуется, чтобы вернуть ранее недоступный сервер обратно в ротацию. Подбор этих значений — практический компромисс между быстрой реакцией на реальный отказ и устойчивостью к кратковременным единичным сбоям сети, не отражающим реальное состояние сервера.

Алгоритмы балансировки: roundrobin, leastconn и другие

roundrobin — простейший и наиболее предсказуемый алгоритм, распределяющий последовательные запросы по кругу между всеми доступными серверами в равной пропорции; он хорошо подходит, когда серверы в пуле обладают сопоставимой производительностью и типичное время обработки отдельного запроса примерно одинаково между разными запросами.

Балансировка по числу активных соединений с учётом относительного веса серверов
backend web_servers
    balance leastconn
    server web1 10.0.0.11:80 check
    server web2 10.0.0.12:80 check weight 2
    server web3 10.0.0.13:80 check

leastconn направляет каждое новое соединение на сервер с наименьшим текущим числом активных подключений — этот алгоритм заметно лучше roundrobin справляется с ситуацией, когда время обработки отдельных запросов сильно различается (например, часть запросов — быстрые чтения из кеша, а часть — тяжёлые отчёты с обращением к базе данных), поскольку не позволяет медленным запросам накапливаться на одном сервере просто потому, что подошла его очередь по кругу.

Параметр weight позволяет задать относительный вес конкретного сервера в пуле — полезно, когда серверы в пуле физически неоднородны (например, один сервер мощнее остальных после частичного апгрейда инфраструктуры) и должны получать пропорционально больше или меньше трафика, чем остальные, без изменения самого алгоритма балансировки. Помимо этих двух наиболее распространённых алгоритмов, HAProxy поддерживает и другие: source (привязка клиента к серверу на основе хеша его IP-адреса, полезно для примитивной привязки сессии без внешнего хранилища) и uri (балансировка на основе хеша пути запроса, полезная для повышения эффективности локального кеша на каждом сервере за счёт того, что одинаковые URL стабильно попадают на один и тот же сервер).

Stick tables: состояние клиентов прямо в балансировщике

Stick table — внутренняя структура данных, которую HAProxy хранит в памяти и обновляет на основе проходящего через него трафика, привязывая произвольный ключ (чаще всего IP-адрес клиента) к набору счётчиков и метаданных — количество запросов за период, к какому серверу был привязан клиент в прошлый раз, и другие показатели.

Отслеживание частоты подключений с одного IP и блокировка при превышении порога
frontend web_front
    bind *:80
    stick-table type ip size 100k expire 10m rate(10s)
    tcp-request connection track-sc0 src
    tcp-request connection reject if { src_conn_rate gt 50 }

В этом примере HAProxy отслеживает частоту новых TCP-соединений с каждого уникального IP-адреса за скользящее окно в 10 секунд и отклоняет новые подключения от адреса, превысившего порог в 50 соединений за этот период, — это простой, но эффективный встроенный механизм ограничения частоты запросов (rate limiting) прямо на уровне балансировщика, без необходимости разворачивать для этого отдельный сервис или модуль.

Другое частое применение stick tables — привязка сессии к конкретному бэкенд-серверу (session persistence, или sticky sessions) на основе значения cookie или IP-адреса клиента, что важно для приложений, хранящих состояние сессии локально на конкретном сервере, а не в общем внешнем хранилище вроде Redis — без такой привязки последовательные запросы одного и того же пользователя, случайно направленные на разные серверы алгоритмом балансировки, увидели бы разные, несинхронизированные копии его сессии.

SSL termination и встроенная статистика

HAProxy умеет принимать HTTPS-соединения и расшифровывать их самостоятельно (SSL/TLS termination) прямо на уровне балансировщика, передавая на бэкенд-серверы уже расшифрованный обычный HTTP-трафик, — это снимает нагрузку на шифрование с самих бэкенд-серверов и централизует управление сертификатами в одном месте.

Приём HTTPS-соединений с явным указанием сертификата и передачей признака протокола на бэкенд
frontend web_front_ssl
    bind *:443 ssl crt /etc/haproxy/certs/example.com.pem
    http-request set-header X-Forwarded-Proto https
    default_backend web_servers

Заголовок X-Forwarded-Proto нужно передавать явно, поскольку после расшифровки TLS на уровне балансировщика бэкенд-сервер получает уже обычное HTTP-соединение и без этого заголовка не может знать, что исходный запрос клиента был по HTTPS — многие приложения используют этот заголовок для корректного формирования абсолютных ссылок на собственные страницы и для решения о необходимости редиректа на HTTPS.

Отдельная практичная возможность — встроенная страница статистики, включаемая директивой stats enable вместе с указанием пути и учётных данных для доступа: она показывает в реальном времени состояние каждого сервера в каждом backend, текущее число активных соединений, результат последней проверки здоровья и накопленную статистику по трафику, без необходимости разворачивать для этой единственной цели отдельную систему мониторинга вроде Prometheus и Grafana, хотя для полноценного долгосрочного мониторинга такая интеграция всё равно рекомендуется.

Когда HAProxy действительно лучше nginx для балансировки

Честный ответ на вопрос "что лучше" в этой паре — оба инструмента способны балансировать HTTP-трафик между несколькими серверами, и для простой схемы с равномерным распределением round-robin между несколькими равноценными бэкендами разница в практическом результате минимальна, а конфигурация в обоих случаях занимает буквально несколько строк.

HAProxy предпочтительнее, когда реально нужны продвинутые health checks с проверкой конкретного HTTP-эндпоинта и гибкой настройкой чувствительности через inter/fall/rise, сложная маршрутизация на основе множества ACL-условий, комбинируемых логическими операторами, stick tables для встроенного ограничения частоты запросов или привязки сессии без внешнего хранилища, а также когда важна детальная встроенная статистика по состоянию каждого бэкенда без развёртывания отдельной системы мониторинга.

nginx, в свою очередь, оправданно проще выбрать, когда балансировка нагрузки — лишь одна из многих задач одного и того же сервера, который уже и так обслуживает статику, выполняет функции обратного прокси для PHP-FPM или другого обработчика приложения и, возможно, кеширует ответы — держать для этого отдельный процесс HAProxy имеет смысл только тогда, когда его дополнительные возможности балансировки действительно используются, а не добавляют лишний компонент в архитектуру без реальной практической выгоды.

На практике многие production-архитектуры используют оба инструмента вместе, а не выбирают один вместо другого: HAProxy на переднем крае принимает весь входящий трафик, распределяет его между несколькими серверами приложения и следит за их состоянием через продвинутые health checks, а на каждом из этих серверов nginx выполняет свою привычную работу — отдаёт статику и проксирует динамические запросы дальше в PHP-FPM или другой бэкенд конкретного приложения.

Тайм-ауты и защита от медленных или зависших клиентов

Отдельная область, где конфигурация HAProxy требует осознанного внимания, — тайм-ауты на разных этапах обработки соединения: timeout connect ограничивает время ожидания установления соединения с бэкенд-сервером, timeout client — время ожидания данных от самого клиента, а timeout server — время ожидания ответа от бэкенда после отправки ему запроса. Слишком большие значения этих тайм-аутов позволяют медленным или намеренно затягивающим соединение клиентам надолго занимать ресурсы балансировщика, а слишком маленькие — обрывают легитимные, но чуть более медленные запросы раньше времени.

Набор тайм-аутов, ограничивающих каждый этап обработки запроса от установления соединения до ответа бэкенда
defaults
    timeout connect 5s
    timeout client 30s
    timeout server 30s
    timeout http-request 10s
    timeout queue 30s

Директива timeout http-request отдельно ограничивает время, за которое клиент должен полностью передать заголовки HTTP-запроса, — это защищает от атак вроде Slowloris, при которых клиент намеренно передаёт заголовки запроса по одному байту с большими паузами, стремясь удерживать открытыми как можно больше соединений и исчерпать лимит одновременных подключений сервера. Без разумного ограничения этого тайм-аута такая атака способна создать реальную проблему доступности даже при относительно небольшом числе одновременных вредоносных соединений.

Директива timeout queue ограничивает время, которое запрос может провести в очереди ожидания, если все серверы в backend уже заняты обработкой предыдущих запросов (актуально при использовании ограничения maxconn на конкретный сервер) — по истечении этого времени HAProxy вернёт клиенту ошибку вместо неограниченного ожидания, что предпочтительнее полного зависания запроса на неопределённый срок при кратковременном всплеске нагрузки, превышающем текущую пропускную способность пула бэкендов.

Итог: инструмент под конкретную задачу балансировки

HAProxy — не замена nginx и не универсально более совершенный инструмент, а специализированное решение именно для задачи балансировки нагрузки и постоянного контроля состояния бэкендов, с заметно более глубоким и гибким набором возможностей именно в этой узкой области, чем у nginx, для которого балансировка — лишь одна из многих встроенных функций универсального веб-сервера.

Выбор между ними стоит делать не по абстрактной репутации инструментов, а по реальному набору требований конкретного проекта: если достаточно простого равномерного распределения между несколькими бэкендами, nginx, скорее всего, уже закрывает эту задачу без необходимости добавлять в архитектуру ещё один компонент. Если же нужны сложные health checks, детальная ACL-маршрутизация или встроенное ограничение частоты запросов через stick tables — опишите архитектуру проекта в заявке внизу страницы, поможем спроектировать схему балансировки под реальную нагрузку.

почему мы

Почему стоит выбрать нас

Быстрый запуск

Подберём конфигурацию и развернём проект в день обращения.

Надёжность

NVMe-диски, защита от DDoS и резервные копии по расписанию.

Поддержка 24/7

Дежурные инженеры на связи в любое время суток.

Настройка под ключ

Установим CMS, настроим веб-сервер, SSL и почту за вас.

Перенос без простоя

Аккуратно перенесём сайт и базу данных на новый сервер.

Прозрачные цены

Актуальные тарифы и честный подбор без навязывания.

частые вопросы

Вопросы и ответы

HAProxy — это веб-сервер, как nginx?

Нет, HAProxy не умеет отдавать статические файлы и не предназначен для этого — это специализированный балансировщик нагрузки и прокси уровней L4 (TCP) и L7 (HTTP), спроектированный исключительно для приёма соединений и их распределения между серверами, тогда как nginx изначально веб-сервер с постепенно добавленными функциями обратного прокси и балансировки.

Можно ли использовать HAProxy и nginx вместе на одном проекте?

Да, и это распространённая практическая схема — HAProxy принимает входящий трафик и распределяет его между несколькими бэкенд-серверами, на каждом из которых работает nginx, обслуживающий статику и передающий динамические запросы дальше в PHP-FPM или другой обработчик приложения.

Что такое stick table и зачем оно нужно?

Stick table — внутренняя структура данных HAProxy, хранящая информацию о клиентах (например, число запросов с конкретного IP-адреса за период) прямо в памяти самого балансировщика, что позволяет реализовать ограничение частоты запросов, отслеживание аномального поведения клиента и привязку сессии к конкретному серверу без обращения к внешнему хранилищу.

Какой алгоритм балансировки выбрать по умолчанию?

roundrobin — разумный выбор по умолчанию для серверов с примерно одинаковой мощностью и однородной нагрузкой на запрос; leastconn предпочтительнее, когда время обработки отдельных запросов заметно различается, поскольку он направляет новое соединение на сервер с наименьшим текущим числом активных подключений, а не просто по очереди.

Нужны ли health checks, если серверы и так редко падают?

Да, health checks нужны не только на случай полного отказа сервера — они также ловят ситуации частичной деградации: например, приложение зависло, но сам процесс всё ещё жив и слушает порт, и без активной проверки конкретного HTTP-эндпоинта такой сервер продолжил бы получать трафик, отвечая ошибками, пока кто-то не заметит проблему вручную.

Насколько сложнее настроить HAProxy по сравнению с nginx для простой балансировки?

Для базовой схемы с двумя-тремя бэкендами и простым алгоритмом round-robin сложность сопоставима — обе конфигурации занимают буквально несколько строк; разница в сложности проявляется, когда нужны продвинутые health checks, ACL-based маршрутизация или stick tables, где у HAProxy готовый и хорошо документированный синтаксис, а у nginx для того же результата обычно нужны сторонние модули или более сложные обходные конструкции.

Поддерживает ли HAProxy SSL/TLS termination?

Да, HAProxy умеет принимать HTTPS-соединения и расшифровывать их самостоятельно (SSL termination), передавая на бэкенд уже расшифрованный HTTP-трафик, либо работать в режиме сквозной передачи TCP-соединения без расшифровки (SSL passthrough), если расшифровка должна выполняться уже на самом бэкенд-сервере.

Есть ли у HAProxy готовая панель мониторинга состояния бэкендов?

Да, встроенная страница статистики (stats page), включаемая директивой stats enable в конфигурации, показывает в реальном времени состояние каждого бэкенда, число активных соединений, статус health checks и накопленную статистику по каждому серверу без необходимости разворачивать отдельную систему мониторинга только для этой цели.

Как оплачивать услуги?

Оплата помесячная, для облачных серверов доступна почасовая тарификация. Принимаются карты, банковские переводы и электронные кошельки.

Есть ли круглосуточная поддержка?

Да, дежурные инженеры на связи 24/7.

Выдаёте ли закрывающие документы?

Да, предоставим необходимые документы для оплаты.

Как оставить заявку?

Заполните форму на странице или нажмите «Заказать» — мы свяжемся и поможем с подбором.

заявка

Оставьте заявку

Ответим и поможем с подбором и настройкой.