haproxy (баллансировщик)

Thank you for reading this post, don't forget to subscribe!

HAProxy это ПО с откры­тым исход­ным кодом, а так же быст­рый и надеж­ный балан­си­ров­щик  нагруз­ки для TCP и HTTP-при­ло­же­ний, посред­ством рас­пре­де­ле­ния вхо­дя­щих запро­сов на несколь­ко обслу­жи­ва­ю­щих серверов.

1. Подготовка бэкендов

На каж­дый сер­вер уста­но­вим web сер­вер nginx

rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm

yum -y install nginx

2. Уста­нов­ка балансировщика

При выбо­ре сер­ве­ра для балан­си­ров­щи­ка сто­ит исхо­дить из того, что 1Гб ОЗУ хва­та­ет для обслу­жи­ва­ния при­мер­но 20-30 тысяч одно­вре­мен­ных сес­сий, дру­ги­ми сло­ва­ми, пока ваш сер­вис не вырос до раз­ме­ров фейс­бу­ка или твит­те­ра, для рабо­ты балан­си­ров­щи­ка будет доста­точ­но почти любо­го сервера.

yum -y install haproxy

3. Настройка балансировщика

mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.backup

Кон­фи­гу­ра­ци­он­ный файл состо­ит из несколь­ких сек­ций. Неко­то­рые сек­ции (frontend, backend, listen) долж­ны иметь своё имя, неко­то­рые (напри­мер, defaults) - могут, но не обя­за­ны, неко­то­рые (global) - не должны.

Доба­вим гло­баль­ные настройки:

Здесь мы дали HAProxy сле­ду­ю­щие указания:

  • log - вести лог в /dev/log сохра­няя в "объ­ект" local0
  • chroot - настрой­ки без­опас­но­сти, "запи­ра­ю­щие" HAProxy в ука­зан­ной директории
  • stats socket - настрой­ки соке­та, по кото­ро­му будет пере­да­вать­ся статистика
  • maxconn - мак­си­маль­ное коли­че­ство кон­ку­ри­ру­ю­щих соеди­не­ний на один процесс
  • user - поль­зо­ва­тель, от име­ни кото­ро­го будет запу­ще­на программа
  • group - груп­па поль­зо­ва­те­ля, от име­ни кото­ро­го будет запу­ще­на программа
  • daemon - запуск про­цес­са как демона

Выста­вим зна­че­ния по умолчанию:

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

  • log - ука­зы­ва­ет, в какой лог вести запи­си (global в дан­ном слу­чае озна­ча­ет, что исполь­зу­ют­ся пара­мет­ры, задан­ные в сек­ции global)
  • mode - уста­нав­ли­ва­ет про­то­кол вза­и­мо­дей­ствия, при­ни­ма­ет одно из зна­че­ний: tcp, http, health
  • retries - коли­че­ство попы­ток соеди­не­ния с сер­ве­ром в слу­чае отказа
  • option httplog - фор­мат лога, в слу­чае исполь­зо­ва­ния HAProxy для прок­си­ро­ва­ния HTTP-запро­сов, реко­мен­ду­ет­ся вклю­чать дан­ную настройку
  • option redispatch - раз­ре­ша­ет про­грам­ме разо­рвать и пере­на­зна­чить сес­сию в слу­чае отка­за сервера
  • contimeout - мак­си­маль­ное вре­мя ожи­да­ния успеш­но­го соеди­не­ния с сервером

 

Теперь ука­жем HAProxy, какие запро­сы он дол­жен слу­шать, для это­го нуж­на сек­ция frontend, кото­рую в нашем при­ме­ре мы назо­вём "front":

Пара­метр bind со зна­че­ни­ем *:80 гово­рит о том, что HAProxy дол­жен при­ни­мать все запро­сы на 80-й порт. Пара­метр default_backend ука­зы­ва­ет, какие сер­ве­ра будут обра­ба­ты­вать эти запро­сы. В дан­ном слу­чае - backend_servers, так мы назва­ли сле­ду­ю­щую секцию:

В этой сек­ции мы зада­ли алго­ритм балан­си­ров­ки (пара­метр balance) и спи­сок сер­ве­ров-обра­бот­чи­ков (server). В каче­стве алго­рит­ма балан­си­ров­ки мы ука­за­ли про­стей­ший roundrobin, более подроб­но раз­лич­ные агло­рит­мы будут рас­смот­ре­ны ниже.
При пере­чис­ле­нии сер­ве­ров исполь­зу­ет­ся сле­ду­ю­щий фор­мат: клю­че­вое сло­во server, назва­ние сер­ве­ра, IP-адрес, допол­ни­тель­ные пара­мет­ры (в дан­ном слу­чае - зада­ние весов).

Теперь всё гото­во к тести­ро­ва­нию, одна­ко, веро­ят­но, вы захо­ти­те сле­дить за состо­я­ни­ем сво­ей "фер­мы" и её ста­ти­сти­кой, для это­го доба­вим ещё одну сек­цию в файл конфигурации:

  • bind :80 озна­ча­ет, что HAProxy будет ожи­дать запро­сы к пор­ту 80
  • stats enable - вклю­чить отчё­ты со статистикой
  • stats uri - уста­нов­ка адре­са стра­ни­цы с отчётом
  • stats auth - логин и пароль для авто­ри­за­ции на стра­ни­це со ста­ти­сти­кой (может быть зада­но несколько)

Таким обра­зом, в дан­ной сек­ции мы ука­за­ли HAProxy, что он дол­жен пока­зы­вать ста­ти­сти­ку на стра­ни­це "/haproxy_stats" на пор­ту 10001, если поль­зо­ва­тель вве­дёт логин "admin" и пароль "password".

 

Конеч­ный вид кон­фиг фай­ла будет следующим:

global
log /dev/log local0

chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon

stats socket /var/lib/haproxy/stats

defaults
mode http
log global
option httplog
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000

frontend front
bind *:80
default_backend backend_servers

backend backend_servers
balance roundrobin
server backend1 192.168.1.155:81 weight 1
server backend2 192.168.1.156:80 weight 5
server backend3 192.168.1.157:80 weight 3

listen stats
bind :80
stats enable
stats uri /haproxy_stats
stats auth admin:password

 

Перед пере­за­пус­ком, реко­мен­ду­ем про­ве­рить синтаксис
haproxy -f /etc/haproxy/haproxy.cfg -c

4.Тестирование

Пере­хо­дим в бра­у­зе­ре по адре­су балан­си­ров­щи­ка, в моём при­ме­ре это 192.168.1.155 . На экране я вижу стро­ку "Welcome to Backend #1!" - эту стро­ку отда­ёт пер­вый бэкенд. Обно­вив стра­ни­цу, полу­чаю "Welcome to Backend #2!" - ответ от дру­го­го бэкен­да. Про­дол­жая нажи­мать F5 я полу­чаю после­до­ва­тель­но адре­са всех бэкен­дов. Здесь сто­ит упо­мя­нуть про веса сер­ве­ров, кото­рые мы зада­ли в сек­ции backend: вес выра­жа­ет­ся чис­лом от 0 до 256, и запро­сы рас­пре­де­ля­ют­ся меж­ду сер­ве­ра­ми про­пор­ци­о­наль­но их весу, что при­ме­ня­ет­ся в основ­ном для рас­пре­де­ле­ния запро­сов меж­ду сер­ве­ра­ми с раз­ной мощностью/производительностью. Мы видим, что отве­ты от сер­ве­ра, кото­ро­му зада­ли боль­ший вес, при­хо­дят чаще, чем от двух других.
Посмот­рим ста­ти­сти­ку. Для это­го нам нуж­но под­клю­чить­ся, исполь­зуя пара­мет­ры, задан­ные в сек­ции stats: вво­жу в адрес­ной стро­ке бра­у­зе­ра 192.168.1.155:10001/haproxy_stats

5. Выбор алгоритма балансировки

HAProxy пред­ла­га­ет несколь­ко алго­рит­мов балан­си­ров­ки, и в зави­си­мо­сти от вашей зада­чи мож­но выбрать наи­бо­лее подходящий:

  • roundrobin - каж­дый сер­вер полу­ча­ет запро­сы про­пор­ци­о­наль­но сво­е­му весу, при этом веса сер­ве­ров могут менять­ся на лету
  • static-rr - то же, что и roundrobin, толь­ко изме­не­ние весов на лету не даст ника­ко­го эффекта
  • leastconn - выби­ра­ет сер­вер с наи­мень­шим коли­че­ством актив­ных соединений
  • first - выби­ра­ет пер­вый сер­вер с доступ­ны­ми сло­та­ми для соединения
  • source - на осно­ве хэша IP-адре­са отпра­ви­те­ля запро­са и весов сер­ве­ров назна­ча­ет­ся сер­вер для соединения
  • uri - сер­вер выби­ра­ет­ся на осно­ве адре­са (без пара­мет­ров) страницы
  • url_param - сер­вер выби­ра­ет­ся на осно­ве GET-пара­мет­ров запроса
  • hdr - сер­вер выби­ра­ет­ся на осно­ве заго­лов­ков запроса
  • rdp-cookie - сер­вер выби­ра­ет­ся на осно­ве cookie (если они не уста­нов­ле­ны, то при­ме­ня­ет­ся обыч­ный round robin)