Балансировщик HAProxy
Это первая статья из цикла про HAProxy. Здесь я затрону базовые понятия и уровни распределения запросов.
Итак, если увеличивается нагрузка, пути строго два: увеличивать производительность сервера, либо добавлять новые сервера и объединять их в кластер. Оба способа помогут справиться с нагрузкой, но вот с отказоустойчивостью у первого не очень, так как мало пользы от мощного сервера, если он лежит. С кластером в этом плане жить комфортно: упала одна нода — подхватили остальные, да и предела для масштабирования нет.
С объединением нескольких серверов в кластер мы и подходим к необходимости распределять нагрузку между ними. Эту задачу решает балансировщик. В D2C мы используем HAProxy, поэтому расскажу варианты его конфигурации в зависимости от архитектуры, которую надо получить на выходе. Все с примерами.
Что такое HAProxy и почему он подойдет
HAProxy — это балансировщик нагрузки, который умеет распределять и проксировать запросы по TCP и HTTP протоколу. Преимуществ у него немало:
- Он бесплатный.
- Он легкий и шустрый, способен обрабатывать 20 тысяч запросов в секунду, а то и больше.
- Он хорош для http-трафика.
- Его несложно вклинить в уже работающий проект.
- У него простая конфигурация и поэтому его можно быстро настроить под свои нужды.
Еще HAProxy использует Airbnb, Alibaba, Github, Instagram, Vimeo и еще не менее сорока известных высоконагруженных проектов. Так что причины его использовать весьма основательны.
Подробнее о том, чем Хапрокси является и не является в официальной документации
Базовые понятия конфигурации
Настройка HAProxy обычно сосредоточена вокруг пяти разделов: global, defaults, frontend, backend, реже listen.
Раздел global определяет общую конфигурацию для всего HAProxy
Defaults определяет настройки по-умолчанию для остальных разделов проксирования.
Раздел listen объединяет в себе описание для фронтенда и бэкенда и содержит полный список прокси. Он полезен для TCP трафика.
Раздел Frontend определяет, каким образом перенаправлять запросы к бэкенду в зависимости от того, что за запрос поступил от клиента.
Секция Backend содержит список серверов и отвечает за балансировку нагрузки между ними в зависимости от выбранного алгоритма
Разделы global, defaults и listen я затрагивать в статье почти не буду, поэтому просто дам стандартную конфигурацию из панели D2C, которую достаточно взять и применить:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
tune.ssl.default-dh-param 2048
defaults
log global
mode http
option httplog
option dontlognull
option http-server-close
option http-pretend-keepalive
option forwardfor
option originalto
retries 3
option redispatch
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
default-server init-addr last,libc,none
А вот на разделах Frontend и Backend я остановлюсь подробнее. Они помогут нам настроить балансировщик исходя из наших задач.
Frontend и типы распределения нагрузки
Фронтенд обычно отвечает за тип распределения нагрузки и выбор бэкенда исходя из правил списков контроля доступа (ACL).
Транспортный уровень или Layer 4
Самый простой способ распределения нагрузки — транспортный или Layer 4. В этом случае HAProxy будет выбирать Бэкенд в зависимости от порта, на который поступил запрос. Например, если запрос поступил на http://ваш-сайт.ру, то трафик обработает Бэкенд, отвечающий за 80 порт.
Пример конфигурации фронтенда для работы на транспортном уровне:
frontend haproxy
mode tcp
bind *:80
default_backend http-backend
- mode. Тип распределения нагрузки. В данном случае мы используем транспортный, поэтому указан протокол TCP. Если указать http, HAProxy станет работать на прикладном уровне (Layer 7).
- bind. IP Адрес и порт, которые HAProxy должен слушать «на входе».
- default_backend. Название конфигурации группы серверов, к которым надо направить запрос для обработки. В данном случае запросы пойдут к backend с названием http-backend.
На Бэкенде так же придется прописать mode tcp. В случае с транспортным уровнем конфигурация бэкенда может выглядеть так:
backend web_server_tcp
mode tcp
balance roundrobin
server srv1 luna-1:80 check
server srv2 luna-2:80 check
В HAProxy в одном конфигурационном файле допустимо использовать несколько типов распределения нагрузки. Например, можно для 80 порта задать режим http и распределять нагрузку на 7 уровне, а для 443 задать TCP и перенаправлять запросы на 4 уровне.
Такая функциональность будет полезна при работе с SSL: можно переадресовать запросы с 80 порта на 443:
frontend http_frontend *:80
mode http
redirect scheme https code 301 if !{ ssl_fc }
потом на транспортном уровне передать обработку запросов дальше:
frontend https_frontend_ssl_pass
mode tcp
bind *:443
default_backend https-backend
и тогда уже сервера на бэкенде будут разбираться с SSL, а не HAProxy
Так будет выглядеть схема. В этом случае HAProxy передаст запрос на транспортном уровне, а его терминация произойдет на одном из серверов бэкенда.
Прикладной уровень или Layer 7
Прикладной уровень посложнее. Однако он позволит запускать несколько групп серверов приложений на одном домене и распределять между ними запросы в зависимости от их содержания.
Распределение нагрузки на прикладном уровне пригодится, если, например, один сайт состоит из разных веб-приложений.
Покажу на примере. Допустим, для блога используется WordPress, на сайте самописный движок на php, а личный кабинет требует Node-js для фронтенда. И все это обслуживают разные команды разработчиков, которые работают в нескольких git репозиториях.
При таком раскладе вы бы точно захотели разъединить все это физически. В этом помогут списки контроля доступа (ACL). Чтобы решить задачу, распределим трафик в завимости от пути на сайте:
- если запрос идет к основному сайту http://ваш-сайт.ру, будем отправлять на Бэкенд №1 к NGINX, который отдает страницы промосайта;
- при обращении к блогу по адресу /blog на Бэкенд №2 к Варнишам, которые кэшируют наш Блог;
- при обращении к кабинету /cabinet на Бэкенд №3 с Nodejs.
Пример распределения нагрузки на прикладном уровне
Так схема выглядит в конфигурации фронтенда:
frontend http bind *:80 mode http acl url_blog path_beg /blog use_backend backend-2 if url_blog acl url_cabinet path_beg /cabinet use_backend backend-3 if url_cabinet default_backend backend-1
- mode http сообщает о том, чтобы HAProxy работал на уровне 7 по http-протоколу;
- инструкция acl url_blog path_beg /blog создает правило url_blog, которое будет срабатвать при обращении по этому адресу;
- инструкция use_backend backend-2 if url_blog сообщает, что если срабатывает правило url_blog, надо отправлять запросы к списку серверов на backend-2;
- default_backend backend-1 говорит о том, что по умолчанию отправлять всех к списку серверов на backend-1, если ни одно правило не сработало.
На бэкенде мы так же пропишем mode http:
backend web_server_tcp
mode http
balance roundrobin
server srv1 luna-1:80 check
server srv2 luna-2:80 check
На этом всё, в следующей статье цикла расскажу про секцию Backend и разные алгоритмы балансировки.
Запомнить
- HAProxy — это быстрый бесплатный TCP/HTTP балансировщик нагрузки
Настройка HAProxy обычно сосредоточена вокруг пяти разделов: global, defaults, frontend, backend, реже listen. При этом первые 2 задают общие параметры по-умолчанию, а основная настройка происходит в последних трёх секциях.
- HAProxy умеет работать на транспортном (Layer 4) и прикладном (Layer 7).
- Чтобы распределять нагрузку на транспортном уровне нужно прописать mode tcp, на прикладном — mode http
- В HAProxy в одном конфигурационном файле допустимо использовать несколько типов распределения запросов
- Чтобы настроить гибкие правила распределения, нужно в секции Frontend прописать правила для списков управления доступом (ACL)
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.