
HAProxy — программа, которая принимает соединения и HTTP-запросы, направляет их серверам и проверяет готовность получателей. Её используют как обратный прокси и балансировщик. Она может работать на Linux-сервере, виртуальной машине или в другой поддерживаемой среде; специальное устройство с надписью HAProxy не требуется.
Здесь соберём учебный пример: один вход, два простых веб-сервера, проверки, статистика, отказ и возврат узла. Все адреса прослушивания — 127.0.0.1, отдельные порты и отдельный каталог. Это лабораторная схема на одном хосте, а не отказоустойчивый производственный кластер. Документация проверена 13 ноября 2026 года; реального запуска HAProxy при подготовке статьи не было.
Что получает бизнес от HAProxy
Обращается к входу сервиса.
Применяет правила и выбирает сервер.
Выполняет операцию и возвращает ответ.
HAProxy — программа-посредник. Состояние приложения и сохранность данных требуют своих механизмов.
- Управляемый вход: правила обработки обращений и передача нужному приложению.
- Распределение: несколько получателей вместо единственного веб-узла, если приложение поддерживает такую архитектуру.
- Обслуживание: вывод узла из обычной ротации и наблюдение за оставшимися соединениями.
- Диагностика: события проверок, ошибки, выбранные серверы, очереди и длительность этапов.
HAProxy не реплицирует базу и не переносит память упавшего процесса. Сессии, файлы, фоновые задания и резервные копии проектируют отдельно. Общий принцип разобран в статье о балансировщике нагрузки.
Frontend, backend и режимы HTTP/TCP
Адрес + порт + правила входа
Адрес и порт первого получателя.
Адрес и порт второго получателя.
Названия секций — логические роли. Они не обозначают отдельные физические устройства.
Frontend принимает обращения на заданном адресе и порту. Backend описывает группу получателей, алгоритм и связанные проверки. Server внутри backend — имя конкретного участника с адресом и портом.
HAProxy понимает HTTP: доступны правила по путям, заголовкам и прикладные действия.
Обслуживает поток TCP без обычной HTTP-логики. Нельзя просто перенести сюда правило проверки URL.
В нашем примере используется HTTP. Для реального протокола режим, TLS и способы проверки подбирают отдельно. Базовые роли показаны в документации frontend. Поддержка UDP и других функций зависит от конкретного продукта: Community, Enterprise и аппаратное решение нельзя считать одинаковыми по составу.
План лаборатории: четыре терминала и пять портов
Точка входа HTTP, терминал C
Терминал A; ответ backend-a.
Терминал B; ответ backend-b.
Отказ процесса A можно показать отдельно. Потеря всего хоста остановит все эти компоненты: физической отказоустойчивости здесь нет.
Нужен отдельный Linux-контур семейства Debian/Ubuntu с доступными пакетами HAProxy, Python 3, curl, socat и OpenSSL. В терминале A будет backend A, в B — backend B, в C — HAProxy, в D — команды проверки. Терминалы должны относиться к одному хосту и пользователю.
18081и18082— два тестовых HTTP-сервера.18080— общий HTTP-вход.18404— локальная страница статистики.18443— необязательный HTTPS-вход во второй части.
Сначала убедитесь, что эти порты свободны и каталог ~/avg-haproxy-lab не содержит нужных данных. В примере создаются и перезаписываются только учебные файлы с явно заданными именами. Пакетная установка может запустить штатную службу HAProxy; лаборатория не использует её конфигурацию и не требует останавливать её.
Шаг 1. Проверяем инструменты и готовим каталог
sudo apt-get update
sudo apt-get install haproxy python3 curl socat openssl
haproxy -vv
python3 --version
curl --versionapt-get update обновляет сведения о пакетах, install устанавливает инструменты на выбранном учебном хосте. Если они уже установлены, достаточно проверить версии. haproxy -vv показывает версию и сборочные возможности: сохраните этот вывод для протокола. Сверяйтесь с руководством именно своей ветки; примеры здесь используют базовые директивы из документации HAProxy 3.2, а не обещание совместимости с любой сборкой.
mkdir -p "$HOME/avg-haproxy-lab/backend-a" "$HOME/avg-haproxy-lab/backend-b"
printf 'backend-a\n' > "$HOME/avg-haproxy-lab/backend-a/index.html"
printf 'backend-b\n' > "$HOME/avg-haproxy-lab/backend-b/index.html"
printf 'ok\n' > "$HOME/avg-haproxy-lab/backend-a/healthz"
printf 'ok\n' > "$HOME/avg-haproxy-lab/backend-b/healthz"mkdir -p создаёт два каталога. В index.html записывается различимый ответ каждого узла; healthz содержит ответ проверки. Это тестовые данные без авторизации и СУБД. Python http.server используется только в лаборатории: документация Python не рекомендует его для production.
Шаг 2. Запускаем два получателя и проверяем их отдельно
Терминал A
python3 -m http.server 18081 --bind 127.0.0.1 --directory "$HOME/avg-haproxy-lab/backend-a"Сервер A слушает только локальный адрес на порту 18081 и отдаёт файлы своего каталога. Терминал остаётся занят процессом; его не закрывают до проверки отказа.
Терминал B
python3 -m http.server 18082 --bind 127.0.0.1 --directory "$HOME/avg-haproxy-lab/backend-b"Сервер B выполняет ту же задачу на порту 18082 с другим содержимым.
Терминал D
curl --noproxy '*' --max-time 3 http://127.0.0.1:18081/
curl --noproxy '*' --max-time 3 http://127.0.0.1:18082/
curl --noproxy '*' --max-time 3 --include http://127.0.0.1:18081/healthzОжидаем различимые ответы backend-a, backend-b и успешный ответ ресурса готовности. Если прямой доступ не работает, сначала проверьте процессы, адреса, порт и файлы. Настройка балансировки не исправляет отсутствие самого backend.
Шаг 3. Создаём полный учебный конфиг
В терминале D выполните блок целиком. Он записывает отдельный haproxy.cfg внутри лабораторного каталога; /etc/haproxy/haproxy.cfg не изменяется.
cat > "$HOME/avg-haproxy-lab/haproxy.cfg" <<'HAPROXY'
global
log stdout format raw local0
maxconn 100
stats socket ./lab.sock mode 600 level admin
defaults
mode http
log global
option httplog
timeout connect 2s
timeout client 15s
timeout server 15s
timeout http-request 5s
timeout queue 3s
frontend lab_http
bind 127.0.0.1:18080
acl blocked_path path_beg -i /admin
http-request deny deny_status 403 if blocked_path
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Proto http
default_backend app_pool
backend app_pool
balance roundrobin
option httpchk
http-check send meth GET uri /healthz ver HTTP/1.1 hdr Host lab.local
http-check expect status 200
default-server inter 2s fall 3 rise 2
server app_a 127.0.0.1:18081 check
server app_b 127.0.0.1:18082 check
frontend lab_stats
bind 127.0.0.1:18404
stats enable
stats uri /stats
stats refresh 5s
HAPROXY- global: локальный вывод журнала, небольшой учебный предел соединений и административный UNIX-сокет с правами 600.
- defaults: HTTP-режим и общие таймауты для последующих секций.
- lab_http: локальный вход, демонстрационная ACL и передача в
app_pool. - app_pool: два сервера, round robin и проверка конкретного ресурса с ожидаемым HTTP 200.
- lab_stats: локальная статистика без включения административных действий в веб-панели.
Ограничения в 100 соединений и секунды ожидания выбраны для маленького стенда; это не норматив производительности для портала или 1С. Полный набор правил и контексты директив описаны в Configuration Manual 3.2.
Шаг 4. Проверяем синтаксис, затем запускаем HAProxy
cd "$HOME/avg-haproxy-lab"
haproxy -c -f haproxy.cfg-c проверяет конфигурацию, -f задаёт файл. Переходите дальше только при успешном завершении проверки. Она не доказывает доступность backend и корректность бизнес-операции.
В терминале C:
cd "$HOME/avg-haproxy-lab"
haproxy -db -f haproxy.cfg-db оставляет HAProxy на переднем плане. Журнал идёт в этот терминал. Рабочий каталог важен: ./lab.sock создаётся относительно него. Порт ниже 1024 не используется, поэтому запуск лаборатории не требует sudo.
Если процесс сообщает о занятом порте или сокете, проверьте, не запущен ли уже ваш экземпляр. Не удаляйте сокет и не завершайте все процессы HAProxy вслепую. Сначала установите, какой процесс относится к лаборатории.
Шаг 5. Проверяем общий вход и распределение
Десять отдельных запусков curl.
Round robin при заданной конфигурации.
backend-a и backend-b, если оба готовы.
Не фиксируем, кто ответит первым. Серия функциональных запросов не является нагрузочным тестом.
for request_no in $(seq 1 10); do
curl --noproxy '*' --silent --show-error --max-time 3 http://127.0.0.1:18080/
doneДесять отдельных обращений должны показать ответы обоих готовых узлов. Не требуйте, чтобы первым обязательно ответил A, и не делайте по десяти запросам вывод о нагрузочной ёмкости. Сопоставьте ответы со статистикой и журналом.
--noproxy '*' исключает влияние внешнего прокси для локального опыта; --max-time ограничивает длительность одного обращения. Если каждый раз отвечает один узел, проверьте состояние второго, результат health check и конфигурацию; не объявляйте round robin сломанным без этих данных.
Что именно проверяет /healthz
Отдельный контрольный запрос HAProxy.
Сравнивается результат проверки.
Неуспехи исключают, успехи возвращают.
Статический healthz в опыте не проверяет базу, права и рабочую функцию приложения.
HAProxy отправляет GET на /healthz и ожидает статус 200. inter 2s задаёт обычный интервал, fall 3 — порог последовательных неуспехов, rise 2 — успешных проверок для возврата. Эти значения не дают точного обещания «переключение за шесть секунд»: влияют фаза проверки, таймауты и состояние.
В стенде /healthz — статический файл. Он подтверждает только доступность тестового HTTP-ресурса, а не готовность базы, лицензии или функции 1С. Для приложения смысл readiness согласуют с разработчиками и эксплуатацией. Нельзя каждые две секунды запускать тяжёлый отчёт ради проверки.
Метод, URI, Host и ожидаемый ответ описаны в официальном руководстве health checks. Открытый TCP-порт и правильный ответ приложения — разные уровни проверки.
Шаг 6. Останавливаем A, наблюдаем отказ и возвращаем его
Ctrl+C только в его терминале.
После обнаружения отказа A.
Возврат после успешных проверок.
В переходном интервале возможны ошибки. Их нужно учитывать в результатах, а не скрывать.
- В терминале A нажмите Ctrl+C: остановится только его тестовый Python-сервер.
- В терминале D повторите серию из десяти обращений. До обнаружения отказа возможны ошибки; фиксируйте их, а не вырезайте из результата.
- После исключения A новые обращения должны обслуживаться готовым B. Проверьте состояние в статистике.
- В терминале A снова выполните команду запуска на 18081 из шага 2.
- После успешных проверок повторите обращения: A должен вернуться в ротацию.
Это проверка отказа процесса на одном хосте. Она не подтверждает устойчивость к потере хоста: при выключении этой Linux-машины исчезнут HAProxy и оба backend. Работавший на потерянном узле запрос также не обязан автоматически завершиться на соседнем.
Шаг 7. Открываем статистику и понимаем цвета
curl --noproxy '*' --max-time 3 --output /dev/null --write-out 'HTTP %{http_code}\n' http://127.0.0.1:18404/statsНа самом учебном хосте откройте http://127.0.0.1:18404/stats. Если браузер на другом компьютере, его 127.0.0.1 указывает на него самого: используйте согласованный защищённый доступ, а не меняйте слушатель на публичный адрес ради удобства.


Выше — реальные фрагменты интерфейса из документации HAProxy, без подмены чисел. Это не снимки нашего учебного запуска. Смотрите состояние app_a/app_b, счётчики обращений, текущие соединения и ошибки проверок. Состояние процесса наверху не заменяет готовность конкретного backend.
Полное назначение панели приведено в Statistics dashboard. Административные действия в веб-панели у нас не включены. В рабочей системе нужны согласованные доступы, аутентификация и защищённый путь; публиковать такую панель всем посетителям нельзя.
Шаг 8. Выводим узел на обслуживание через Runtime API
Ограничение обычного выбора; проверки продолжаются.
Возврат из административного вывода; готовность ещё проверяется.
Учитывают persistence и существующие соединения. В данном стенде привязка сеансов не настроена.
Убедитесь, что оба тестовых сервера снова работают. В терминале D:
cd "$HOME/avg-haproxy-lab"
printf 'set server app_pool/app_a state drain\n' | socat - UNIX-CONNECT:./lab.sock
printf 'show stat\n' | socat - UNIX-CONNECT:./lab.sockКоманда через локальный UNIX-сокет переводит A в drain. В нашем стенде нет sticky sessions, поэтому новые обычные запросы должны идти к B; уже открытые соединения рассматриваются отдельно. Контрольные запросы к A продолжаются.
cd "$HOME/avg-haproxy-lab"
printf 'set server app_pool/app_a state ready\n' | socat - UNIX-CONNECT:./lab.sockready снимает административный вывод, но не заставляет неработающий сервер успешно пройти проверки. maint имеет другой смысл: приостанавливает и обычный трафик, и проверки соответствующего сервера. Точные свойства описаны в set server.
При привязке сеансов поведение drain имеет исключения: это не универсальная кнопка «никаких новых обращений». Runtime-изменения в этом примере не записываются в файл и не должны считаться сохранёнными после перезапуска. Для постоянной политики нужен отдельный управляемый процесс.
Шаг 9. Проверяем ACL и границу доверия к заголовкам
curl --noproxy '*' --max-time 3 --include http://127.0.0.1:18080/adminДля /admin ожидается 403 от HAProxy, потому что правило blocked_path использовано в http-request deny. Само объявление ACL без действия ничего не запрещает. path_beg -i /admin охватывает и другие пути с таким префиксом: это демонстрация механизма, а не полноценная защита административных интерфейсов.
В HTTP-входе мы заново задаём X-Forwarded-For из адреса непосредственного клиента и X-Forwarded-Proto как http. Модель рассчитана на единственный внешний вход перед приложением; цепочка из нескольких доверенных прокси требует другой согласованной обработки. Backend должен доверять сведениям только от назначенного посредника.
Правила по пути доступны именно в HTTP-режиме. Порядок, условия и действия разобраны в руководстве ACL. Такая ACL не заменяет аутентификацию, WAF и права приложения.
Шаг 10. Необязательный HTTPS-вход без отключения проверки сертификата
Этот блок создаёт короткоживущий самоподписанный сертификат только для лаборатории. Приватный ключ остаётся в каталоге пользователя. Не используйте его для внешнего портала и не устанавливайте его доверие всем рабочим станциям.
cd "$HOME/avg-haproxy-lab"
umask 077
openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 7 -keyout lab-key.pem -out lab-cert.pem -subj "/CN=lab.example.test" -addext "subjectAltName=DNS:lab.example.test"
cat lab-cert.pem lab-key.pem > lab.pem
chmod 600 lab-key.pem lab.pemumask 077 ограничивает права новых файлов. OpenSSL создаёт ключ и сертификат с именем lab.example.test и SAN на семь дней. lab.pem объединяет сертификат и ключ для учебного входа HAProxy.
Скопируйте основной конфиг и добавьте HTTPS-frontend:
cd "$HOME/avg-haproxy-lab"
cp haproxy.cfg haproxy-tls.cfg
cat >> haproxy-tls.cfg <<'HAPROXY_TLS'
frontend lab_https
bind 127.0.0.1:18443 ssl crt ./lab.pem
acl blocked_path path_beg -i /admin
http-request deny deny_status 403 if blocked_path
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Proto https
default_backend app_pool
HAPROXY_TLSЗдесь HTTPS завершается на HAProxy, а к тестовым Python-серверам запрос идёт по локальному HTTP. При необходимости защищённого второго участка в рабочей сети отдельно настраивают TLS, доверие, имя и проверку backend. Возможности TLS зависят от сборки и версии; официальное руководство также показывает современные варианты управления сертификатами.
Проверьте новый файл в терминале D:
cd "$HOME/avg-haproxy-lab"
haproxy -c -f haproxy-tls.cfgЕсли проверка успешна, остановите только лабораторный HAProxy в терминале C через Ctrl+C и запустите там вариант haproxy -db -f haproxy-tls.cfg из того же каталога. Затем в D:
cd "$HOME/avg-haproxy-lab"
curl --noproxy '*' --resolve lab.example.test:18443:127.0.0.1 --cacert lab-cert.pem --max-time 5 https://lab.example.test:18443/--resolve подставляет локальный адрес для имени и порта. --cacert задаёт доверие этому сертификату только для обращения. Проверка имени сохраняется; ключ -k не нужен. Успешный запрос должен вернуть ответ одного готового узла. Это ожидаемый результат опыта, а не выполненный нами TLS-тест.
Таймауты, журнал и разбор ошибки
- timeout connect: ожидание установления соединения с получателем.
- timeout client / server: пределы неактивности соответствующих сторон, а не универсальная максимальная длительность бизнес-операции.
- timeout http-request: ограничение времени приёма HTTP-запроса в предусмотренном директивой смысле.
- timeout queue: допустимое ожидание в очереди. Увеличивать его без контроля нагрузки нельзя.
В терминале C виден HTTP-журнал: сопоставляйте выбранный backend/server, код, время и состояние завершения. Не записывайте пароли и токены ради подробности. В рабочем проекте задают ротацию, защиту и историю изменений; лог в терминале — учебный способ наблюдения.
При 503 смотрят наличие готовых серверов и ограничения; при таймауте — сеть, ожидание backend и приложение. При 403 проверяют собственные правила и права. Один HTTP-код не определяет причину без журналов и контекста.
Что изменить перед настоящей публикацией приложения
- Определить домены, протоколы, сети, TLS и допустимые входы. Закрыть обходной доступ к backend.
- Согласовать готовность приложения, данные, сессии, фоновые задачи, ограничения и профиль нагрузки.
- Настроить доверие к исходному клиенту и проверять реальную авторизацию, файлы, редиректы и долгие операции.
- Перенести конфигурацию в управляемый сервисный процесс с контролем версий, правами, проверкой и возвратом.
- Настроить мониторинг и журналы, закрытый административный доступ и безопасное хранение сертификатов.
- Испытать отказ узла, остаточную производительность, обслуживание и восстановление данных.
Ubuntu/Debian-пакет и HAProxy Enterprise могут иметь разные способы установки, сервисные пути и функции. Пример не требует платной редакции, но не гарантирует доступность любой функции во всех продуктах. Полезно отдельно читать материал о прямом и обратном прокси.
Два HAProxy и одна база: где ещё остаются отказы
Нужны доступный вход и согласованные настройки.
Нужны независимые ресурсы и остаточная мощность.
СУБД, сессии, файлы и копии проектируются отдельно.
Это уровни проекта, не утверждение, что учебная однохостовая схема уже их реализует.
Пара HAProxy требует механизма доступного входа и согласованных конфигураций, сертификатов, сетей и необходимых состояний. VRRP/плавающий IP применимы не в любой облачной сети; готовый адрес нельзя переносить между произвольными подсетями.
Синхронизация некоторых таблиц привязки не переносит автоматически активные TCP-соединения, память приложения и транзакции СУБД. Два backend на одном физическом хосте остаются зависимыми от него. Общие база, хранилище, DNS, питание и канал также могут быть единичными точками отказа.
Для бизнес-сервиса задают критерии: допустимые ошибки, задержки, время восстановления, целостность операций и поведение пользователя. Ни синтаксическая проверка, ни зелёный цвет панели сами по себе не заменяют приёмку.
Файлы лаборатории и карточка приёмки
Поможем внедрить и сопровождать входной слой
ИТ-аутсорсинг
- Обследование зависимостей и доступов.
- Настройка HAProxy, журналов и мониторинга.
- Регламент обновления, проверки и возврата.
Согласуем результаты работ и границы ответственности.
Обсудить сопровождениеОблачные ресурсы
- Ресурсы для входа и приложения.
- Подбор размещения и сетевой схемы.
- Тестовый контур и план переноса.
Выберем инфраструктуру под реальные задачи.
Подобрать ресурсыВопросы и ответы
Можно ли запустить пример на рабочем сервере?
Для первого опыта используйте отдельный согласованный контур. Не заменяйте существующую конфигурацию и не останавливайте чужие процессы.
Почему используется 127.0.0.1?
Чтобы учебные серверы и панель не открывались внешним клиентам. Все процессы в примере работают на одном хосте.
Проверка haproxy -c подтверждает работу сайта?
Нет. Она проверяет конфигурацию. Доступность, распределение, авторизацию и бизнес-операции проверяют отдельно.
Сколько занимает обнаружение отказа?
Зависит от интервалов, порогов, таймаутов и фазы проверки. Измеряйте фактическое время и ошибки в своём контуре.
Drain полностью запрещает обращения к серверу?
Не во всех схемах: учитывают привязку и существующие соединения. В нашем простом опыте persistence не настроен.
Нужен ли root для запуска лаборатории?
Для установки пакетов нужны административные права; выбранные порты и сокет в каталоге пользователя позволяют запускать сам учебный процесс без sudo.
HAProxy делает резервные копии базы?
Нет. СУБД, состояние приложения и резервное копирование требуют отдельных механизмов.
Скриншоты статистики получены на этом стенде?
Нет. Это подписанные фрагменты официальной документации HAProxy. Реальный запуск и переключение при подготовке статьи не выполнялись.
