Балансировка бэкендов с помощью Nginx

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

Балан­си­ров­ка нагруз­ки меж­ду несколь­ки­ми при­ло­же­ни­я­ми, бэкен­да­ми и сер­ве­ра­ми явля­ет­ся частью про­цес­са опти­ми­за­ции ресур­сов, улуч­ше­ния про­из­во­ди­тель­но­сти и отка­зо­устой­чи­во­сти сервиса.

Nginx как load balancer

Этот веб-сер­вер счи­та­ет­ся одним из самых попу­ляр­ных и про­из­во­ди­тель­ных реше­ний, ведь име­ет широ­чай­ший функ­ци­о­нал и гиб­кость при настрой­ке. Так что Nginx часто исполь­зу­ет­ся для балан­си­ров­ки нагрузки.

Под­хо­дов и реа­ли­за­ций несколь­ко, но преж­де про­верь­те нали­чие моду­ля ngx_http_upstream_module:

# Все уста­нов­лен­ные и исклю­чен­ные моду­ли будут содер­жать­ся в выводе

Если же он отсут­ству­ет, то при­дет­ся пере­со­брать Nginx, доба­вив этот модуль.

После это­го мож­но при­сту­пать к настрой­ке веб-сер­ве­ра. Для вклю­че­ния балан­си­ров­ки добавь­те дирек­ти­ву upstream (сек­ция http) в файл кон­фи­гу­ра­ции Nginx:

# Мож­но назна­чить несколь­ко дирек­тив upstream

Теперь нуж­но ука­зать пере­на­прав­ле­ние необ­хо­ди­мой группы:

# Пере­на­прав­ле­ние так­же мож­но ука­зать в дирек­ти­вах fastcgi_pass, memcached_pass, uwsgi_pass, scgi_pass

Кро­ме это­го Nginx под­дер­жи­ва­ет допол­ни­тель­ные пара­мет­ры и мето­ды рас­пре­де­ле­ния нагрузки.

Выбор метода балансировки

Nginx пред­ла­га­ет несколь­ко мето­дов балан­си­ров­ки нагрузки.

Round-robin

Веб-сер­вер по умол­ча­нию рас­пре­де­ля­ет запро­сы рав­но­мер­но меж­ду бэкен­да­ми (но с уче­том весов). Этот стан­дарт­ный метод в Nginx, так что дирек­ти­ва вклю­че­ния отсутствует.

least_conn

Запро­сы сна­ча­ла отправ­ля­ют­ся бэкен­ду с наи­мень­шим коли­че­ством актив­ных под­клю­че­ний (но с уче­том весов):

# Если коли­че­ство актив­ных соеди­не­ний оди­на­ко­во, то допол­ни­тель­но исполь­зу­ет­ся метод round-robin

Hash и IP hash

При помо­щи это­го мето­да мож­но создать сво­е­го рода посто­ян­ные соеди­не­ния меж­ду кли­ен­та­ми и бэкендами.

Для каж­до­го запро­са Nginx вычис­ля­ет хэш, кото­рый состо­ит из тек­ста, пере­мен­ных веб-сер­ве­ра или их ком­би­на­ции, а затем сопо­став­ля­ет его с бэкендами:

# Для вычис­ле­ния хэша исполь­зу­ет­ся схе­ма (http или https) и пол­ный URL

IP hash рабо­та­ет толь­ко с HTTP, это пред­опре­де­лен­ный вари­ант, в кото­ром хэш вычис­ля­ет­ся по IP-адре­су клиента:

# Если адрес кли­ен­та IPv4, то для хэша исполь­зу­ет­ся пер­вые три окте­та, если IPv6, то весь адрес

Веса бэкендов

Если в сте­ке опре­де­лен­ные бэкен­ды мощ­нее, чем дру­гие, то при­го­дят­ся веса:

# По умол­ча­нию веса рав­ны 1

В этом при­ме­ре из каж­дых 16 запро­сов пер­вый бэкенд будет обра­ба­ты­вать 10, вто­рой 5, а тре­тий 1. При этом бэкап-сер­вер будет полу­чать запро­сы толь­ко если три основ­ных бэкен­да недоступны.

Мониторинг

Если Nginx счи­та­ет, что бэкенд сер­вер недо­сту­пен, то вре­мен­но пере­ста­ет слать на него запро­сы. За это отве­ча­ет две директивы:

  • max_fails — зада­ет коли­че­ство неудач­ных попы­ток под­клю­че­ний, после кото­рых бэкенд опре­де­лен­ное вре­мя счи­та­ет­ся недоступным;
  • fail_timeout — вре­мя, в тече­ние кото­ро­го сер­вер счи­та­ет­ся недоступным.

Пара­мет­ры выгля­дят так:

# Пара­мет­ры по умол­ча­нию: 1 попыт­ка, 10 секунд таймаута