Балансировка нагрузки с помощью HAProxy
Пример горизонтального масштабирования для распределения запросов между несколькими серверами для повышения отказоустойчивости.
Рассмотрим решение по балансировке нескольких веб-серверов при помощи сервиса HAProxy.
Технические требования
- Сервер под балансировщик с двумя сетевыми интерфейсами (Рекомендация. Внешний адрес для связи с внешним миром и локальный для общения между узлами кластера);
- Два и более серверов под распределение запросов/трафика;
В примере будет использоваться дистрибутив Linux CentOS 7.
Установка и настройка backend-серверов
В качестве backend-серверов я буду использовать несколько веб-серверов с NGINX и настроенным SSL.
Прежде всего установим NGINX
1 | yum install nginx |
Выполним настройку веб-сервера
1 | server { |
Конфигурацию SSL можно выполнить и на самом балансировщике, а бэкенд сервера оставить работать на 80 порту, но в моем случае я буду использовать режим SSL Pass-Through
. Не забываем поместить SSL-сертификаты в директорию /etc/nginx/ssl
.
Для того, чтобы принимать реальные IP-адреса клиентов на веб-сервере от HAProxy необходимо добавить proxy_protocol
в параметр listen, а также указать реальный адрес откуда разрешить принимать запросы:
1 | set_real_ip_from 10.0.1.10/32; |
Создадим приветственную страницу на обоих веб-серверах touch /srv/www/devservers.network/public_html
со следующим содержимым, изменив только номер сервера для его дальнейшего определения:
1 |
|
Добавляем NGINX в автозагрузку и запускаем сервис.
1 | systemctl enable nginx |
И не забываем выполнить настройку Firewalld
1 | firewall-cmd --permanent --add-service=https |
Установка и настройка балансировщика
В качестве сервера балансировки я буду использовать VDS сервер с ресурсами 1 vCPU и 1Gb RAM. При правильной настройке, данных мощностей хватит для обслуживания 10-15к одновременных сессий, чего вполне достаточно для среднестатистического интернет-ресурса.
Установим HAProxy
Пакет HAProxy доступен в базовой репозитории CentOS.
1 | yum install haproxy |
Настройка HAProxy
HAProxy обладает очень гибкими настройками и конфигурация может содержать большое количество директив и условий. Конфигурационный файл состоит из нескольких секций. Директивы frontend, backend, listen должны иметь своё имя, к примеру defaults - может, но не обязательно, а такие как global - не должны.
Выполняем конфигурацию HAProxy в файле /etc/haproxy/haproxy.cfg
.
Рекомендую использовать свой конфигурационный файл, а представленный по умолчанию оставить как резерв.
Секция global
1 | global |
Рассмотрим настройки в директиве global
:
- log - вести лог в
/dev/log
сохраняя в local0; - chroot - настройки безопасности, позволяющие работать HAProxy только в указанной директории;
- maxconn - максимальное количество соединений на один процесс;
- daemon - запуск процесса как демона.
Секция defaults
В секции defaults описываются параметры по умолчанию для всех других секций, следующих за данной. В файле конфигурации может быть несколько секций defaults, в этом случае параметры, описанные в данной секции, будут переопределены в следующей, и будут применяться к секциям, идущим за ней.
В нашем примере указаны следующие параметры:
1 | defaults |
- log - указывает в какой лог вести запись (global в данном случае означает, что используются параметры, заданные в секции global);
- mode - устанавливает протокол взаимодействия, принимает одно из значений:
tcp
,http
,health
; - retries - количество попыток соединения с сервером в случае отказа;
- option httplog - формат лога, в случае использования HAProxy для проксирования HTTP-запросов (рекомендуется включить данную настройку);
- option redispatch - разрешает программе разорвать и переназначить сессию в случае отказа сервера;
- contimeout - максимальное время ожидания успешного соединения с сервером.
В примере я использую параметры timeout
, которые позволяют более гибко настроить поведение балансировщика. Подробно с доступными параметрами можно ознакомиться в документации к HAProxy
Секция frontend
Укажем HAProxy какие запросы он должен обрабатывать, для этого задаем секцию frontend с именем https-in
:
1 | frontend https-in |
Параметр bind со значением *:443
говорит о том, что HAProxy должен принимать все запросы на 443-й порт. Ещё раз напомню, что в данном примере я использую режим SSL Pass-Through
, поэтому настройка SSL на самом HAProxy не выполняется.
Параметр default_backend указывает, какие сервера будут обрабатывать эти запросы. В данном случае - backend-https-servers, именно так необходимо назвать секцию backend.
Секция backend
В этой секции мы задаем алгоритм балансировки (параметр balance) и список серверов-обработчиков (server). В качестве алгоритма балансировки указываем roundrobin.
HAProxy имеет несколько алгоритмов балансировки:
roundrobin
- каждый сервер получает запросы пропорционально своему весу, при этом веса серверов могут меняться на лету;static-rr
- то же, что и roundrobin, только изменение весов на лету не даст никакого эффекта;leastconn
- выбирает сервер с наименьшим количеством активных соединений;first
- выбирает первый сервер с доступными слотами для соединения
source - на основе хэша IP-адреса отправителя запроса и весов серверов назначается сервер для соединения;uri
- сервер выбирается на основе адреса (без параметров) страницы;url_param
- сервер выбирается на основе GET-параметров запроса;hdr
- сервер выбирается на основе заголовков запроса;rdp-cookie
- сервер выбирается на основе cookie (если они не установлены, то применяется обычный roundrobin);
При перечислении серверов используется следующий формат: ключевое слово server, имя сервера, IP-адрес, дополнительные параметры (в данном случае - проверка статуса хоста и Proxy Protocol, которые позволяет перенаправлять реальные IP-адреса клиента с HAProxy на веб-сервер).
1 | backend backend-https-servers |
Просмотр статистики HAProxy
Для включения расширенной статистики HAProxy необходимо в конфигурационный файл добавить секцию:
1 | listen stats |
bind :10001
- HAProxy будет ожидать запросы к порту 10001;stats enable
- включить отчёты со статистикой;stats uri
- установка адреса страницы с отчётом;stats auth
- логин и пароль для авторизации на странице со статистикой;
В секции listen
указываем HAProxy, что он должен показывать статистику на странице /haproxy_stats
на порту 10001 после ввода логина admin
и пароля password
.
Проверяем.
Переходим по адресу HAProxy (IP-адрес или хостнйем) и просто обновляем страницу. В зависимости от выбранного балансировщиком сервера будем получать ответ This is server #1
либо This is server #2
.
Проверяем статистику. Переходим по адресу SITE_NAME:10001/haproxy_stats
На этом всё. Выше рассмотрен самый простой метод балансировки. Более сложная настройка требует грамотно составленного ТЗ и технических данных проекта. HAProxy очень удобный и гибкий в настройке инструмент с помощью которого можно выполнить балансировку и других сервисов, к примеру почтовый сервер, Memcached, Redis и пр.