Используемые термины: NGINX, http, https, веб-сервер.
В данной инструкции мы рассмотрим процесс настройки балансировки, в основном, http-запросов с помощью веб-сервера NGINX. По большей части, инструкция подойдет для любого дистрибутива Linux, и даже, Windows (за исключением путей расположения конфигурационных файлов). Таким образом настроенный NGINX сможет обеспечить распределение нагрузки и отказоустойчивость нашим сетевым сервисам.
Обратите внимание, что NGINX умеет распределять не только http-запросы. Его можно использовать для балансировки запросов на 4-м уровне модели OSI (TCP и UDP), например, подключения к СУБД, DNS и так далее — по сути, любой сетевой запрос может быть обработан и распределен с помощью данного программного продукта.
Постепенно рассмотрим разные варианты настройки распределения нагрузки в NGINX. Начнем с простого понимания, как работает данная функция и закончим некоторыми примерами настройки балансировки.
Чтобы наш сервер мог распределять нагрузку, создадим группу веб-серверов, на которые будут переводиться запросы:
vi /etc/nginx/conf.d/upstreams.conf
* в данном примере мы создаем файл upstreams.conf, в котором можем хранить все наши апстримы. NGINX автоматически читает все конфигурационные файлы в каталоге conf.d.
Добавим:
upstream admins24_backend { server 192.168.10.10; server 192.168.10.11; server 192.168.10.12;}
* предполагается, что в нашей внутренней сети есть кластер из трех веб-серверов — 192.168.10.10, 192.168.10.11 и 192.168.10.12. Мы создали апстрим с названием admins24_backend. Позже, мы настроим веб-сервер, чтобы он умел обращаться к данному бэкенду.
В настройках сайта (виртуального домена) нам необходимо теперь проксировать запросы на созданный upstream. Данная настройка будет такой:
server { … location / { proxy_pass http://admins24_backend; } …}
* данная настройка для нашего сайта укажет, что все запросы мы должны переводить на апстрим admins24_backend (который, в свою очередь, будет отправлять запросы на три сервера).
Проверяем корректность нашего конфигурационного файла:
Если ошибок нет, перезапускаем сервис:
systemctl restart nginx
При настройке бэкендов мы можем указать, кому наш веб-сервер будет отдавать больше предпочтение, а кому меньше.
Синтаксис при указании веса:
server <имя сервера> weight=<числовой эквивалент веса>;
По умолчанию приоритет равен 1.
Также мы можем указать опции:
Давайте немного преобразуем нашу настройку upstreams:
upstream admins24_backend { server 192.168.10.10 weight=100; server 192.168.10.11 weight=10; server 192.168.10.12; server 192.168.10.13 backup;}
* итак, мы указали нашему серверу:
По умолчанию, NGINX будет считать сервер недоступным после 1-й неудачной попытки отправить на него запрос и в течение 10 секунд не будут продолжаться попытки работы с ним. Также каждый сервер не имеет ограничений по количеству к нему подключений.
Изменить поведение лимитов и ограничений при балансировке можно с помощью опций:
Синтаксис:
server <имя сервера> max_fails=<число попыток> fail_timeout=<числовой показатель времени><еденица времени>;
В нашем примере мы преобразуем настройку так:
upstream admins24_backend { server 192.168.10.10 weight=100 max_conns=1000; server 192.168.10.11 weight=10 max_fails=2 fail_timeout=90s; server 192.168.10.12 max_fails=3 fail_timeout=2m; server 192.168.10.13 backup;}
* в итоге:
Рассмотрим способы балансировки, которые можно использовать в NGINX:
Настройка метода балансировки выполняется в директиве upstream. Синтаксис:
upstream <название апстрима> { <метод балансировки> …}
Веб-сервер будет передавать запросы бэкендам по очереди с учетом их весов. Данный метод является методом по умолчанию и его указывать в конфигурационном файле не нужно.
Данный метод определяет контрольную сумму на основе переменных веб-сервера и ассоциирует каждый полученный результат с конкретным бэкендом. Пример настройки:
upstream admins24_backend { hash $scheme$request_uri; server 192.168.10.10; server 192.168.10.11; server 192.168.10.12;}
* это самый распространенный пример настройки hash — с использованием переменных $scheme (http или https) и $request_uri. При данной настройке каждый конкретный URL будет ассоциирован с конкретным сервером.
Ассоциация выполняется исходя из IP-адреса клиента и только для HTTP-запросов. Таким образом, для каждого посетителя устанавливается связь с одним и тем же сервером. Это, так называемый, Sticky Session метод.
Для адресов IPv4 учитываются только первые 3 октета — это позволяет поддерживать одинаковые соединения с клиентами, чьи адреса меняются (получение динамических адресов от DHCP провайдера). Для адресов IPv6 учитывается адрес целиком.
Пример настройки:
upstream admins24_backend { ip_hash; server 192.168.10.10; server 192.168.10.11; server 192.168.10.12;}
NGINX определяет, с каким бэкендом меньше всего соединений в данный момент и перенаправляет запрос на него (с учетом весов).
Настройка выполняется с помощью опции least_conn:
upstream admins24_backend { least_conn; server 192.168.10.10; server 192.168.10.11; server 192.168.10.12;}
Запросы передаются случайным образом (но с учетом весов). Дополнительно можно указать опцию two — если она задана, то NGINX сначала выберет 2 сервера случайным образом, затем на основе дополнительных параметров отдаст предпочтение одному из них. Это следующие параметры:
upstream admins24_backend { random two least_conn; server 192.168.10.10; server 192.168.10.11; server 192.168.10.12;}
Данная опция будет работать только в NGINX Plus. Балансировка выполняется исходя из времени ответа сервера. Предпочтение отдается тому, кто отвечает быстрее.
Опция для указания данного метода — least_time. Также необходимо указать, что мы считаем ответом — получение заголовка (header) или когда страница возвращается целиком (last_byte).
Пример 1:
upstream admins24_backend { least_time header; server 192.168.10.10; server 192.168.10.11; server 192.168.10.12;}
* в данном примере мы будем делать расчет исходя из того, как быстро мы получаем в ответ заголовки.
Пример 2:
upstream admins24_backend { least_time last_byte; server 192.168.10.10; server 192.168.10.11; server 192.168.10.12;}
* в данном примере мы будем делать расчет исходя из того, как быстро мы получаем в ответ целую страницу.
В реальной жизни настройки могут быть несколько сложнее, чем приведенные здесь или в официальной документации. Рассмотрим несколько примеров, что может понадобиться настроить при балансировке.
Предположим, что наши внутренние серверы отвечают по SSL-каналу. Таким образом, нам нужно отправлять запрос по порту 443. Также схема проксирования должна быть https.
Настройка сайта:
server { … location / { proxy_pass https://admins24_backend; 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 момента:
Настройка upstream:
upstream admins24_backend { server 192.168.10.10:443; server 192.168.10.11:443; server 192.168.10.12:443;}
* в данном примере мы указали конкретный порт, по которому должно выполняться соединение с бэкендом. Для упрощения конфига дополнительные опции упущены.
Нам может понадобиться разные страницы сайта переводить на разные группы внутренних серверов.
server { … location /page1 { proxy_pass http://backend1; }
location /page2 { proxy_pass http://backend2; } …}
* при такой настройке мы будем передавать запросы к странице page1 на группу backend1, а к page2 — backend2.
upstream backend1 { server 192.168.10.10; server 192.168.10.11;}
upstream backend2 { server 192.168.10.12; server 192.168.10.13;}
* в данном примере у нас есть 2 апстрима, каждый со своим набором серверов.
Может быть необходимым делать обращение к внутреннему ресурсу по другому hostname, нежели чем будет обращение к внешнему. Для этого в заголовках проксирования мы должны указать опцию Host.
server { … location / { proxy_pass https://admins24_backend; 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.
Рассмотрим, в качестве исключения, TCP-запрос на порт 5432 — подключение к базе PostgreSQL.
server { listen 5432; proxy_pass tcp_postgresql;}
* в данном примере мы слушаем TCP-порт 5432 и проксируем все запросы на апстрим tcp_postgresql.
upstream tcp_postgresql { server 192.168.10.14:5432; server 192.168.10.15:5432;}
* запросы будут случайным образом передаваться на серверы 192.168.10.14 и 192.168.10.15.
Рассмотрим также и возможность балансировки UDP-запросов — подключение к DNS по порту 53.
server { listen 53 udp; proxy_pass udp_dns; proxy_responses 1;}
* в данном примере мы слушаем UDP-порт 53 и проксируем все запросы на апстрим udp_dns. Опция proxy_responses говорит о том, что на один запрос нужно давать один ответ.
upstream udp_dns { server 192.168.10.16:53; server 192.168.10.17:53;}
* запросы будут случайным образом передаваться на серверы 192.168.10.16 и 192.168.10.17.
Возможно, данные инструкции также будут полезны:
1. Примеры редиректов в NGINX.
2. Настройка веб-сервера в Docker.
3. Установка и настройка HAProxy на CentOS.
Продолжая использовать данный сайт вы принимаете политику конфиденциальности и cookies