Файл конфигурации HAProxy короткий по сравнению с большинством серверного ПО, но именно он решает, как каждый запрос попадает в ваше приложение. Если вы собираетесь поставить балансировщик нагрузки перед сайтом или API как шаг к отказоустойчивой настройке серверов или унаследовали балансировщик, в котором никто толком не разбирается, файл полезно прочитать по разделам. В руководстве разобрана типичная конфигурация HAProxy для веб-приложения на актуальных версиях 3.x: что делает каждая часть, какие параметры важнее всего и какие ошибки приводят к авариям.

Четыре раздела конфигурации HAProxy

  • global задаёт параметры всего процесса: журналирование, пользователя, от имени которого работает HAProxy, настройки TLS по умолчанию и административный сокет для Runtime API.
  • defaults содержит настройки, которые наследуют все разделы ниже, прежде всего режим (http или tcp) и тайм-ауты. Отсутствие тайм-аутов — классическая причина скопления соединений, и HAProxy предупреждает об этом при запуске.
  • frontend описывает, что слушает HAProxy: адреса, порты, сертификаты и правила, по которым выбирается backend для каждого запроса.
  • backend перечисляет серверы за балансировщиком, способ распределения трафика между ними и способ проверки их состояния.

После каждой правки команда haproxy -c -f /etc/haproxy/haproxy.cfg проверяет файл до перезагрузки конфигурации. При перезагрузке через systemd запускаются новые процессы с новой конфигурацией, а текущие соединения завершаются на старых.

Пример конфигурации HAProxy словами

Типичная схема для сайта компании с двумя серверами приложения выглядит так:

  • Frontend занимает порт 80 и перенаправляет каждый запрос на HTTPS, а также занимает порт 443 с параметром ssl и каталогом crt, где лежат сертификаты.
  • Правила во frontend отправляют запросы, путь которых начинается с /api, в backend для API, а всё остальное — в веб-backend.
  • В каждом backend есть строка balance, HTTP-проверка состояния и две строки server с ключевым словом check.
  • Frontend добавляет заголовок X-Forwarded-For параметром option forwardfor и устанавливает X-Forwarded-Proto, чтобы приложение записывало в журнал реальные адреса посетителей и знало, что исходный запрос пришёл по HTTPS.

Последний пункт легко упустить. Без этих заголовков приложения за балансировщиком видят всех посетителей с адреса самого HAProxy, а некоторые создают циклы перенаправления, потому что считают, что запрос пришёл по обычному HTTP.

Как выбрать алгоритм балансировки нагрузки

  • roundrobin — алгоритм по умолчанию, распределяет запросы по очереди и учитывает веса серверов. Хорош для коротких однотипных запросов.
  • leastconn отправляет новые соединения на сервер с наименьшим числом активных. Лучше подходит, когда длительность запросов сильно различается: отчёты, загрузки файлов, долгие соединения.
  • source, а также хеш заголовка или URL, закрепляет одного клиента или ресурс за одним сервером. Полезно для кешей, хуже подходит для равномерного распределения нагрузки.

Веса позволяют более мощному серверу получать большую долю, а вес ноль оставляет сервер в конфигурации, но не отправляет на него новые запросы.

Настройка проверки состояния HAProxy, отражающей реальность

Одно ключевое слово check только проверяет, отвечает ли TCP-порт, а это делает и упавшее приложение за работающим веб-сервером. HTTP-проверка состояния HAProxy запрашивает настоящую страницу: option httpchk вместе с http-check send и http-check expect позволяет запросить путь вроде /health и требовать статус 200. Хорошая конечная точка проверки обращается к важным зависимостям, например к базе данных, но не нагружает систему.

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

Привязка сессий HAProxy и SSL-терминация HAProxy

Если приложение хранит вход пользователя или корзину в локальных файлах или памяти, посетитель, попавший на другой сервер, теряет сессию. Лучшее решение — на стороне приложения: хранить сессии в общем месте, например в Redis или в базе данных. Если это невозможно, привязка сессий HAProxy использует директиву cookie в backend, например cookie SERVERID insert indirect nocache, и значение cookie в каждой строке server. Тогда HAProxy закрепляет каждого посетителя за одним сервером и переносит его, только если сервер выходит из строя.

SSL-терминация HAProxy означает, что HAProxy сам обрабатывает TLS и передаёт серверам обычный HTTP по частной сети. Так сертификаты хранятся в одном месте, а HAProxy может читать запросы для маршрутизации. Если путь между HAProxy и серверами проходит через сети, которые вы не контролируете, зашифруйте и этот участок, добавив в строки server параметр ssl и проверку сертификата.

Как вывести сервер из ротации через HAProxy Runtime API

Для развёртывания без простоя выведите один сервер из ротации, обновите его, проверьте и верните обратно. HAProxy Runtime API делает это без правки файла. Через административный сокет, заданный в разделе global, команда вроде set server web/app1 state drain перестаёт направлять новых посетителей на app1, пока текущие сессии завершаются, а state ready возвращает сервер в работу. Скрипты развёртывания могут вывести сервер из ротации таким образом, дождаться, пока число соединений достигнет нуля, и продолжить. Изменения, сделанные через сокет, в файл конфигурации не записываются, поэтому постоянные изменения по-прежнему нужно вносить в него.

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

Часто задаваемые вопросы: конфигурация HAProxy

Может ли один HAProxy обслуживать сайты и другие сервисы?

Да. Одна конфигурация может балансировать сайты в режиме http, а такие сервисы, как базы данных или почта, — в режиме TCP HAProxy, у каждого со своими frontend и backend. В режиме TCP HAProxy пропускает соединения, не читая их.

Какую версию HAProxy выбрать?

Для рабочей среды — ветку с долгосрочной поддержкой, например 3.2. Пакеты дистрибутивов часто отстают от актуальных веток, поэтому проверьте, какая версия реально устанавливается на вашем сервере; проект HAProxy публикует список поддерживаемых веток и ссылается на более новые пакеты для Debian и Ubuntu.

Сколько серверов нужно за HAProxy?

Минимум два для резервирования, и каждый должен выдерживать пиковый трафик в одиночку. Иначе вывод одного из ротации для развёртывания или потеря одного из-за сбоя перегрузит другой в самый неподходящий момент.

Планируете балансировщик или хотите, чтобы вторая пара глаз посмотрела на существующую конфигурацию? Наша услуга установки и настройки балансировщика HAProxy охватывает проверки состояния, TLS-терминацию и отказоустойчивость, спланированные под ваше приложение, для компаний в Лос-Анджелесе и за его пределами. Серверам за балансировщиком обычно тоже нужно внимание; см. нашу услугу оптимизации веб-сервера Apache. Свяжитесь с нами, кратко описав ваши серверы и трафик.