NGINX балансировка нагрузки

В данной статье  описывается возможные настройки балансировки веб-сервера NGINX. По большей части, статья подойдет для любого дистрибутива Linux. Таким образом настроенный NGINX сможет обеспечить распределение нагрузки и отказоустойчивость сетевым сервисам.

Обратите внимание, что NGINX умеет распределять не только http-запросы. Его можно использовать для балансировки запросов на 4-м уровне модели OSI (TCP и UDP), например, подключения к СУБД, DNS и так далее — по сути, любой сетевой запрос может быть обработан и распределен с помощью данного программного продукта.

Основы

Чтобы сервер мог распределять нагрузку, создадим группу веб-серверов, на которые будут переводиться запросы:

vi /etc/nginx/conf.d/upstreams.conf

* в данном примере создается файл upstreams.conf, в котором можем хранить все апстримы. NGINX автоматически читает все конфигурационные файлы в каталоге conf.d.

Впишем:

upstream balansed {
server 192.168.0.10;
server 192.168.0.11;
server 192.168.0.12;
}

* предполагается, что в  внутренней сети есть кластер из трех веб-серверов — 192.168.0.10192.168.0.11 и 192.168.0.12. Апстрим с названием balansed. Далее, настроим веб-сервер, чтобы он умел обращаться к данному бэкенду.

В настройках сайта (виртуального домена) необходимо теперь проксировать запросы на созданный upstream. Данная настройка будет такой:

server {

location / {
proxy_pass http://balansed;
}

}

* данная настройка для нашего сайта укажет, что все запросы мы должны переводить на апстрим balansed (который, в свою очередь, будет отправлять запросы на три сервера).

Проверяем корректность нашего конфигурационного файла:

nginx -t

Если ошибок нет, перезапускаем сервис:

systemctl restart nginx

Приоритеты

При настройке бэкендов можно указать, кому наш веб-сервер будет отдавать больше предпочтение, а кому меньше.

Синтаксис при указании веса:

server <имя сервера> weight=<числовой эквивалент веса>;

По умолчанию приоритет равен 1.

Также можно указать опции:

  • backup, которая будет говорить о наличие резервного сервера, к которому будет выполняться подключение только при отсутствии связи с остальными.
  • down, при указании которой, сервер будет считаться постоянно недоступным. Может оказаться полезной, чтобы остановить временно запросы для проведения обслуживания.

Немного преобразуем настройку upstreams:

vi /etc/nginx/conf.d/upstreams.conf

upstream balansed {
server 192.168.0.10 weight=100;
server 192.168.0.11 weight=10;
server 192.168.0.12;
server 192.168.0.13 backup;
}

* итак, указали нашему серверу:

  • переводить на сервер 192.168.0.10 в 10 раз больше запросов, чем на 192.168.0.11 и в 100 раз больше — чем на 192.168.0.12.
  • переводить на сервер 192.168.0.11 в 10 раз больше запросов, чем на 192.168.0.12.
  • на сервер 192.168.10.13 запросы переводятся, только если не доступны все три сервера.

Задержки, лимиты и таймауты

По умолчанию, NGINX будет считать сервер недоступным после 1-й неудачной попытки отправить на него запрос и в течение 10 секунд не будут продолжаться попытки работы с ним. Также каждый сервер не имеет ограничений по количеству к нему подключений.

Изменить поведение лимитов и ограничений при балансировке можно с помощью опций:

  • max_fails — количество неудачных попыток, после которых будем считать сервер недоступным.
  • fail_timeout — время, в течение которого сервер нужно считать недоступным и не отправлять на него запросы.
  • max_conns — максимальное число подключений, при превышении которого запросы на бэкенд не будут поступать. По умолчанию равно 0 (безлимитно).

Синтаксис:

server <имя сервера> max_fails=<число попыток> fail_timeout=<числовой показатель времени><еденица времени>;

В примере преобразуем настройку так:

vi /etc/nginx/conf.d/upstreams.conf

upstream balansed {
server 192.168.0.10 weight=100 max_conns=1000;
server 192.168.0.11 weight=10 max_fails=2 fail_timeout=90s;
server 192.168.0.12 max_fails=3 fail_timeout=2m;
server 192.168.0.13 backup;
}

* в итоге:

  • сервер 192.168.0.10 будет принимать на себя, максимум, 1000 запросов.
  • сервер 192.168.0.10 будет иметь настройки по умолчанию.
  • если на сервер 192.168.0.11 будет отправлено 2-е неудачные попытки отправки запроса, то в течение 90 секунд на него не будут отправлять новые запросы.
  • сервер 192.168.0.12 будет недоступен в течение 2-х минут, если на него будут отправлены 3 неудачных запроса.

Метод балансировки

Способы балансировки, которые можно использовать в NGINX:

  1. Round Robin.
  2. Hash.
  3. IP Hash.
  4. Least Connections.
  5. Random.
  6. Least Time (только в платной версии NGINX).

Настройка метода балансировки выполняется в директиве upstream. Синтаксис:

upstream <название апстрима> {
<метод балансировки>

}

Round Robin

Веб-сервер будет передавать запросы бэкендам по очереди с учетом их весов. Данный метод является методом по умолчанию и его указывать в конфигурационном файле не нужно.

Hash

Данный метод определяет контрольную сумму на основе переменных веб-сервера и ассоциирует каждый полученный результат с конкретным бэкендом. Пример настройки:

upstream balansed {
hash $scheme$request_uri;
server 192.168.0.10;
server 192.168.0.11;
server 192.168.0.12;
}

* это самый распространенный пример настройки hash — с использованием переменных $scheme (http или https) и $request_uri. При данной настройке каждый конкретный URL будет ассоциирован с конкретным сервером.

IP Hash

Ассоциация выполняется исходя из IP-адреса клиента и только для HTTP-запросов. Таким образом, для каждого посетителя устанавливается связь с одним и тем же сервером. Это, так называемый, Sticky Session метод.

Для адресов IPv4 учитываются только первые 3 октета — это позволяет поддерживать одинаковые соединения с клиентами, чьи адреса меняются (получение динамических адресов от DHCP провайдера). Для адресов IPv6 учитывается адрес целиком.

Пример настройки:

upstream balansed {
ip_hash;
server 192.168.0.10;
server 192.168.0.11;
server 192.168.0.12;
}

Least Connections

NGINX определяет, с каким бэкендом меньше всего соединений в данный момент и перенаправляет запрос на него (с учетом весов).

Настройка выполняется с помощью опции least_conn:

upstream balansed {
least_conn;
server 192.168.0.10;
server 192.168.0.11;
server 192.168.0.12;
}

Random

Запросы передаются случайным образом (но с учетом весов). Дополнительно можно указать опцию two — если она задана, то NGINX сначала выберет 2 сервера случайным образом, затем на основе дополнительных параметров отдаст предпочтение одному из них. Это следующие параметры:

  • least_conn — исходя из числа активных подключений.
  • least_time=header (только в платной версии) — на основе времени ответа (расчет по заголовку).
  • least_time=last_byte (только в платной версии) — на основе времени ответа (расчет по полной отдаче страницы).

Пример настройки:

upstream balansed {
random two least_conn;
server 192.168.0.10;
server 192.168.0.11;
server 192.168.0.12;
}

Least Time

Данная опция будет работать только в NGINX Plus. Балансировка выполняется исходя из времени ответа сервера. Предпочтение отдается тому, кто отвечает быстрее.

Опция для указания данного метода — least_time. Также необходимо указать, что мы считаем ответом — получение заголовка (header) или когда страница возвращается целиком (last_byte).

Пример 1:

upstream balansed {
least_time header;
server 192.168.0.10;
server 192.168.0.11;
server 192.168.0.12;
}

* в данном примере делаться расчет исходя из того, как быстро получаем в ответ заголовки.

Пример 2:

upstream balansed {
least_time last_byte;
server 192.168.0.10;
server 192.168.0.11;
server 192.168.0.12;
}

* в данном примере делаться расчет исходя из того, как быстро получаем в ответ целую страницу.

Сценарии настройки

В реальной жизни настройки могут быть несколько сложнее, чем приведенные здесь или в официальной документации. Рассмотрим несколько примеров, что может понадобиться настроить при балансировке.

1. Backend на https

Предположим, что внутренние серверы отвечают по SSL-каналу. Таким образом, нужно отправлять запрос по порту 443. Также схема проксирования должна быть https.

Настройка сайта:

server {

location / {
proxy_pass https://balansed;
proxy_set_header   Host             $host;
proxy_set_header   X-Real-IP        $remote_addr;
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
}

}

* обратите внимание на 2 момента:

  1. В схеме подключения proxy_pass указали https. В противном случае при подключении NGINX будет возвращать ошибку 400.
  2. Задали дополнительные опции proxy_set_header, которых не было в примерах выше.

Настройка upstream:

upstream balansed {
server 192.168.0.10:443;
server 192.168.0.11:443;
server 192.168.0.12:443;
}

* в данном примере указали конкретный порт, по которому должно выполняться соединение с бэкендом. Для упрощения конфига дополнительные опции упущены.

2. Разные бэкенды для разных страниц

Нам может понадобиться разные страницы сайта переводить на разные группы внутренних серверов.

Настройка сайта:

server {

location /page1 {
proxy_pass http://balansed1;
}

location /page2 {
proxy_pass http://balansed2;
}

}

* при такой настройке будут передавать запросы к странице page1 на группу balansed1, а к page2balansed2.

Настройка upstream:

upstream balansed1 {
server 192.168.0.10;
server 192.168.0.11;
}

upstream balansed2 {
server 192.168.0.12;
server 192.168.0.13;
}

* в данном примере у есть 2 апстрима, каждый со своим набором серверов.

3. На другой хост

Может быть необходимым делать обращение к внутреннему ресурсу по другому hostname, нежели чем будет обращение к внешнему. Для этого в заголовках проксирования мы должны указать опцию Host.

Настройка сайта:

server {

location / {
proxy_pass https://balansed;
proxy_set_header   Host             internal.domain.com;
proxy_set_header   X-Real-IP        $remote_addr;
proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
}

}

* в данном примере будут проксировать запросы на бэкенды, передавая им имя хоста internal.domain.com.

4. TCP-запрос

Рассмотрим, в качестве исключения, TCP-запрос на порт 5432 — подключение к базе PostgreSQL.

Настройка сайта:

server {
listen 5432;
proxy_pass tcp_postgresql;
}

* в данном примере мы слушаем TCP-порт 5432 и проксируем все запросы на апстрим tcp_postgresql.

Настройка upstream:

upstream tcp_postgresql {
server 192.168.0.14:5432;
server 192.168.0.15:5432;
}

* запросы будут случайным образом передаваться на серверы 192.168.0.14 и 192.168.0.15.

5. UDP-запрос

Рассмотрим также и возможность балансировки UDP-запросов — подключение к DNS по порту 53.

Настройка сайта:

server {
listen 53 udp;
proxy_pass udp_dns;
proxy_responses 1;
}

* в данном примере мы слушаем UDP-порт 53 и проксируем все запросы на апстрим udp_dns. Опция proxy_responses говорит о том, что на один запрос нужно давать один ответ.

Настройка upstream:

upstream udp_dns {
server 192.168.0.16:53;
server 192.168.0.17:53;
}

* запросы будут случайным образом передаваться на серверы 192.168.0.16 и 192.168.0.17.

взято из сайта www.dmosk.ru

Оставить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *


Срок проверки reCAPTCHA истек. Перезагрузите страницу.