Пожалуйста, опишите ошибку

Нашли баг? Помогите нам его исправить, заполнив эту форму

HAProxy

Сергей Смелков
web-разработчик

HAProxy (High Availability Proxy) — написанный на C популярный прокси-сервер для Linux, Solaris и FreeBSD с возможностью балансировки нагрузки TCP/HTTP.

Балансировка нагрузки с помощью HAProxy

Введение

HAProxy используется в ряде высоконагруженных веб-сайтов, включая Twitter, GitHub, Imgur и Instagram. HAProxy является программой с открытым исходным кодом и распространяется в соответствии с GNU General Public License (GNU GPL v2). Во многих проектах рано или поздно встаёт вопрос масштабирования. И в этой статье мы расскажем как легко распределить нагрузку между серверами с помощью HAProxy. Так как в интернете достаточно сайтов, на которых подробно расписаны основные моменты и понятия HAProxy, мы перейдём сразу к настройке HAProxy. Подробнее с основными понятиями HAProxy можно ознакомиться здесь. С основной документацией по HAProxy можно ознакомиться здесь
В данной статье будут приведены примеры конфигураций HAProxy для распределения нагрузки между кластером http-серверов и Percona XtraDB Cluster. Начнём с установки HAProxy.

Часть 1. Установка HAProxy

В качестве операционной системы используется Ubuntu 16.04.
sudo apt-get update -y && sudo apt-get install haproxy -y

Настройка

Прежде чем настраивать HAProxy, сделаем бэкап основного конфига, поставляемого с установкой балансировщика.
sudo mv /etc/haproxy/haproxy.cfg{,.backup}
Если вы не сталкивались раньше с этой формой записи, то данная команда преобразуется интерпретатором в следующее
sudo mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup
После установки необходимо включить HAProxy, чтобы балансировщик мог запускаться при помощи скрипта инициализации:
sudo sed -i "s/ENABLED=0/ENABLED=1/" /etc/default/haproxy
Создадим папку для HAProxy, которая пригодится для файла конфигурации. Для чего она нужна, будет рассказано ниже.
sudo mkdir /usr/share/haproxy

Часть 2. Настройка HAProxy для http-серверов

Предположим у вас есть 2 сервера, принимающих http-запросы. В нашем случае это:
  • 172.20.0.2:3000
  • 172.20.0.3:3000
Требуется распределить нагрузки между ними. Приступим к написанию файла конфигурации:
sudo vim /etc/haproxy/haproxy.cfg
Зададим глобальные настройки:
global
    log 127.0.0.1 local1
    maxconn 4096
    chroot /usr/share/haproxy
    user haproxy
    group haproxy
Здесь мы задали следующие параметры:
  • log — этот параметр задаёт логгирование, и здесь мы указали, что логи будут посылаться на ip-адрес 127.0.0.1, т.е. на localhost. local1 — это имя. Где это использовать, будет показано ниже.
  • maxconn — максимальное количество одновременных соединений на один процесс.
  • chroot — настройки безопасности, «запирающие» HAProxy в указанной директории. Данная настройка повышает уровень безопасности в случае, если злоумышленник постарается использовать вашу систему.
  • user — пользователь, от имени которого будет запущена программа.
  • group — группа пользователя, от имени которого будет запущена программа.

Зададим настройки по умолчанию:

defaults
    log global
    option httplog
    mode http
    retries 2
    timeout connect 3000
    timeout server 5000
    timeout client 5000
Рассмотрим эти настройки подробнее:
  • log — указывает, в какой лог вести записи (global в данном случае означает, что используются параметры, заданные в секции global).
  • option httplog — формат лога, в случае использования HAProxy для проксирования HTTP-запросов, рекомендуется включать данную настройку
  • mode — устанавливает протокол взаимодействия, принимает одно из значений: tcp, http, health. В нашем случае http, потому что в данной статье настраивается балансировка для http-серверов.
  • retries — количество попыток соединения с сервером в случае отказа.
  • timeout connect — устанавливает максимальное время ожидания при попытке подключения к серверу.
  • timeout server — устанавливает максимальное время бездействия на стороне сервера.
  • timeout client — устанавливает время бездействия на стороне клиента для незавершенных («полузакрытых») соединений.
Рекомендуется timeout server и timeout client задавать одинаково.
Теперь переходим к главной части. Укажем HAProxy, какие запросы он должен обрабатывать. Эти настройки задаются в части frontend.
frontend haproxy
    bind *:6000
    default_backend back
Здесь мы указали параметр bind со значением *:6000, что HAProxy будет принимать все запросы на порт 6000 (порт можно указать любой свободный). Frontend часть мы назвали haproxy. Параметр default_backend указывает, какой набор серверов (backend) будет обрабатывать эти запросы. В данном примере мы указали, что это будет "back". Так мы и назвали следующую часть:
backend back
    balance roundrobin
    option httpchk
    server s1 172.20.0.2:3000 check inter 3000 rise 2 fall 2 weight 1
    server s2 172.20.0.3:3000 check inter 3000 rise 2 fall 2 weight 2
Рассмотрим эти настройки подробнее:
  • balance roundrobin — указывает алгоритм балансировки (в нашем случае balance roundrobin). Подробнее об алгоритмах балансировки описано ниже.
  • option httpchk — активирует http протокол для проверки состояния серверов. При такой настройке HAProxy будет посылать обычный http-запрос на каждый сервер для проверки состояния. Если сервер вернет статус 200, значит сервер ещё способен принимать запросы, иначе сервер исключается из доступных для перенаправления запроса.
  • server — данная настройка добавляет сервер для перенаправления запросов.
  • check — указывает, что перед направлением запроса на этот сервер необходимо проверить, что сервер ещё доступен.
  • inter — задаёт интервал в милисекундах, через сколько времени необходимо снова проверять сервер на работоспособность
  • rise — указывает, что сервер будет считаться работоспособным после определенного количества проверок.
  • fall — указывает, что сервер будет считаться не работоспособным после определенного количества проверок.
  • weight — задаёт вес (приоритет) сервера.
В конечном итоге файл конфигурации выглядит следующим образом:
global
    log 127.0.0.1 local0 notice
    log 127.0.0.1 local1
    maxconn 4096
    chroot /usr/share/haproxy
    user haproxy
    group haproxy

defaults
    log global
    mode http
    retries 2
    timeout connect 3000
    timeout server 5000
    timeout client 5000

frontend haproxy
    bind *:6000
    default_backend back

backend back
    balance roundrobin
    option httpchk
    server s1 172.20.0.2:3000 check inter 3000 rise 2 fall 2 weight 1
    server s2 172.20.0.3:3000 check inter 3000 rise 2 fall 2 weight 2
Перезапускаем HAProxy и всё готово:
sudo service haproxy restart

Часть 3. Настройка HAProxy для Percona XtraDB Cluster

Предполагается, что для Percona XtraDB Cluster у вас уже настроена Galera мастер-мастер репликация. Предположим есть список серверов:
  • 10.0.1.2:3306
  • 10.0.1.3:3306
  • 10.0.1.4:3306
Настроим HAProxy. Для начала приведём полностью файл конфигурации, а затем некоторые моменты рассмотрим отдельно.
global
    log 127.0.0.1 local1
    maxconn 4096
    chroot /usr/share/haproxy
    user haproxy
    group haproxy
    daemon

defaults
    log global
    option tcplog
    option dontlognull
    retries 3
    option redispatch
    maxconn 2000
    contimeout 5000
    clitimeout 50000
    srvtimeout 50000

frontend pxc-front
    bind *:7033
    mode tcp
    default_backend pxc-back

backend pxc-back
   mode tcp
   timeout client  10800s
   timeout server  10800s
   balance roundrobin
   option httpchk
   option allbackups
   server db1 10.0.1.2:3306 check port 9200 inter 3000 rise 3 fall 3 weight 1
   server db2 10.0.1.3:3306 check port 9200 inter 3000 rise 3 fall 3 weight 3
   server db3 10.0.1.4:3306 check port 9200 inter 3000 rise 3 fall 3 weight 4
Так как значения и смысл многих настроек были описаны в части 2 данной статьи, разберём некоторые из них.
Первым главным отличием от настроек для http-серверов является настройка "mode tcp". MySQL не обрабатывает http-запросы, поэтому запросы перенаправляются по tcp. Но тут может возникнуть вопрос: почему тогда стоит проверка состояния сервера по http? (option httpchk) Сам MySQL http-запросы обрабатывать не будет. Но в состав пакетов Percona XtraDB Cluster входит утилита clustercheck, которая должна быть установлена на каждом сервере. После чего HAProxy будет способен проверять состояние сервера MySQL через HTTP. Скрипт clustercheck — это обычный shell-скрипт, который принимает http-запросы и проверяет MySQL на входящие запросы. Если данный сервер кластера отвечает на запрос MySQL, скрипт возвращает ответ с HTTP кодом 200, иначе он вернёт статус 503. Чтобы установить этот скрипт, необходимо создать clustercheck пользователя:
mysql> grant process on *.* to 'clustercheckuser'@'localhost' identified by 'clustercheckpassword!';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
Если вы хотите использовать другого пользователя или другой пароль, то в скрипте нужно внести эти изменения тоже. В Ubuntu 16.04 этот скрипт находится по пути "/usr/bin/clustercheck". Теперь можно тестировать:
sudo clustercheck
В случае если у вас всё настроено правильно, вы увидите результат:
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: close
Content-Length: 40

Percona XtraDB Cluster Node is synced.
Если вы хотите «демонизировать» скрипт clustercheck, можно использовать xinetd. Для его установки выполняем команду:
sudo apt-get update -y && sudo apt-get install xinetd -y
Новый сервис должен быть настроен в файле /etc/xinetd.d/mysqlchk:
# default: on
# description: mysqlchk
service mysqlchk
{
# this is a config for xinetd, place it in /etc/xinetd.d/
  disable = no
  flags = REUSE
  socket_type = stream
  port = 9200
  wait = no
  user = nobody
  server = /usr/bin/clustercheck
  log_on_failure += USERID
  only_from = 0.0.0.0/0
  # recommended to put the IPs that need
  # to connect exclusively (security purposes)
  per_source = UNLIMITED
}
Также необходимо этот новый сервис добавить в файл "/etc/services":
# Local services
mysqlchk   9200/tcp
После чего перезапускаем xinetd
sudo service xinetd restart
Осталось обратить внимание на последнюю деталь: port 9200. Напомним, что в конфигурации HAProxy для Percona XtraDB Cluster мы писали в backend части следующее:
backend pxc-back
   ...
   option httpchk
   ...
   server db1 10.0.1.2:3306 check port 9200 ...
   server db2 10.0.1.3:3306 check port 9200 ...
   server db3 10.0.1.4:3306 check port 9200 ...
В данном случае говорится, что проверка состояния сервера будет осуществляться путем запроса на порт 9200 каждого сервера. Как раз этот порт мы указывали в файле "/etc/xinetd.d/mysqlchk". На этом насройка HAProxy для Percona XtraDB Cluster завершается. Не забудьте открыть порты на серверах кластера для HAProxy. Напоследок хочется добавить, что не рекомендуется обращаться к MySQL через root пользователя. Следует создать другого пользователя, например:
mysql> GRANT ALL PRIVILEGES ON *.* TO 'haproxy_user'@'10.%' IDENTIFIED BY 'password'; FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
Перезапускаем HAProxy и всё готово:
sudo service haproxy restart

Часть 4. Логи и ещё раз логи

После настройки конфигурации настроим, чтобы все логи записывались в файл. Для этого установим rsyslog.
sudo apt-get update -y && sudo apt-get install rsyslog -y
Напомним, что в глобальных настройках мы задавали:
global
    log 127.0.0.1 local1
    ...
Это означает, что все логи HAProxy будет посылать на localhost. Настроим теперь rsyslog, чтобы он принимал эти логи и записывал в файл:
sudo vim /etc/rsyslog.conf
Расскоментируем следующие строчки:
...
$ModLoad imudp
$UDPServerRun 514

# И добавим следующую строчку
$UDPServerAddress 127.0.0.1
...
Теперь создадим файл /etc/rsyslog.d/haproxy.conf:
sudo vim /etc/rsyslog.d/haproxy.conf
И напишем следующее:
local1.*    /var/log/haproxy.log
Перезапускаем rsyslog и всё готово:
sudo service rsyslog restart
Теперь, чтобы посмотреть логи, можно открыть файл /var/log/haproxy.log либо в терминале выполнить команду:
sudo tail -f /var/log/haproxy.log
Таким образом, новые логи HAProxy автоматически будут появляться в терминале.
Читать и комментировать

Краснодар

Коммунаров, 268,
3 эт, офисы 705, 707

+7 (861) 200 27 34

Хьюстон

3523 Brinton trails Ln Katy

+1 833 933 0204

Москва

+7 (495) 145-01-05