Балансировка нагрузки HTTP
Балансировка нагрузки HTTP-трафика между веб-группами или группами серверов приложений с помощью нескольких алгоритмов и расширенных функций, таких как медленный запуск и сохранение сеанса.
Обзор
Балансировка нагрузки между несколькими экземплярами приложений — это широко используемый метод оптимизации использования ресурсов, увеличения пропускной способности, сокращения задержек и обеспечения отказоустойчивых конфигураций.
Посмотрите вебинар NGINX Plus для балансировки нагрузки и масштабирования по требованию, чтобы подробно изучить методы, которые пользователи NGINX используют для создания крупномасштабных высокодоступных веб-сервисов.
NGINX и NGINX Plus можно использовать в различных сценариях развертывания в качестве очень эффективного балансировщика нагрузки HTTP .
Проксирование HTTP-трафика на группу серверов
Чтобы начать использовать NGINX Plus или NGINX с открытым исходным кодом для балансировки нагрузки HTTP-трафика на группу серверов, сначала необходимо определить группу с помощью upstream
директивы. Директива помещается в http
контекст.
Серверы в группе настраиваются с помощью server
директивы (не путать с server
блоком, определяющим виртуальный сервер, работающий на NGINX). Например, следующая конфигурация определяет группу с именем backend и состоит из трех конфигураций серверов (которые могут разрешаться в более чем трех реальных серверах):
http {
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com;
server 192.0.0.1 backup;
}
}
Для передачи запросов группе серверов имя группы указывается в директиве ( proxy_pass
или директивах fastcgi_pass
, memcached_pass
, scgi_pass
, или uwsgi_pass
для этих протоколов). определено в предыдущем примере:
server {
location / {
proxy_pass http://backend;
}
}
В следующем примере объединены два приведенных выше фрагмента и показано, как проксировать HTTP-запросы к группе внутренних серверов. Группа состоит из трех серверов, на двух из которых запущены экземпляры одного и того же приложения, а третий является сервером резервного копирования. Поскольку в блоке не указан алгоритм балансировки нагрузки upstream
, NGINX использует алгоритм по умолчанию Round Robin:
http {
upstream backend {
server backend1.example.com;
server backend2.example.com;
server 192.0.0.1 backup;
}
server {
location / {
proxy_pass http://backend;
}
}
}
Выбор метода балансировки нагрузки
NGINX Open Source поддерживает четыре метода балансировки нагрузки, а NGINX Plus добавляет еще два метода:
Round Robin — запросы распределяются равномерно по серверам с учетом веса серверов . Этот метод используется по умолчанию (нет директивы для его включения):
upstream backend {
# no load balancing method is specified for Round Robin
server backend1.example.com;
server backend2.example.com;
}
Наименьшее количество подключений — запрос отправляется на сервер с наименьшим количеством активных подключений, опять же с учетом весов серверов :
upstream backend {
least_conn;
server backend1.example.com;
server backend2.example.com;
}
IP-хэш — сервер, на который отправляется запрос, определяется по IP-адресу клиента. В этом случае для вычисления хэш-значения используются либо первые три октета адреса IPv4, либо весь адрес IPv6. Метод гарантирует, что запросы с одного и того же адреса попадают на один и тот же сервер, если он недоступен.
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
}
Если один из серверов необходимо временно исключить из ротации балансировки нагрузки, его можно пометить параметром down , чтобы сохранить текущее хеширование клиентских IP-адресов. Запросы, которые должны были быть обработаны этим сервером, автоматически отправляются на следующий сервер в группе:
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
}
Универсальный хеш — сервер, на который отправляется запрос, определяется с помощью определяемого пользователем ключа, который может быть текстовой строкой, переменной или их комбинацией. Например, ключ может быть парным исходным IP-адресом и портом или URI, как в этом примере:
upstream backend {
hash $request_uri consistent;
server backend1.example.com;
server backend2.example.com;
}
Дополнительный постоянный параметр hash
директивы включает балансировку нагрузки ketama с постоянным хэшем. Запросы равномерно распределяются по всем вышестоящим серверам на основе заданного пользователем значения хешированного ключа. Если вышестоящий сервер добавляется в вышестоящую группу или удаляется из нее, переназначаются только несколько ключей, что сводит к минимуму промахи в кэше в случае кэш-серверов с балансировкой нагрузки или других приложений, накапливающих состояние.
Наименьшее время (только NGINX Plus) — для каждого запроса NGINX Plus выбирает сервер с наименьшей средней задержкой и наименьшим количеством активных подключений, при этом наименьшая средняя задержка рассчитывается на основе того, какие из следующих параметров включены в least_time
директиву:
header
– Время получения первого байта от сервераlast_byte
– Время получения полного ответа от сервераlast_byte inflight
– Время получения полного ответа от сервера с учетом незавершенных запросов
Случайный — каждый запрос будет передан на случайно выбранный сервер. Если two
параметр указан, то сначала NGINX случайным образом выбирает два сервера с учетом весов серверов, а затем выбирает один из этих серверов указанным методом:
least_conn
– Наименьшее количество активных подключенийleast_time=header
(NGINX Plus) — наименьшее среднее время получения заголовка ответа от сервера ($upstream_header_time
)least_time=last_byte
(NGINX Plus) — наименьшее среднее время получения полного ответа от сервера ($upstream_response_time
)
Примечание. При настройке любого метода, кроме Round Robin, поместите соответствующую директиву ( hash
, ip_hash
, least_conn
, least_time
или random
) над списком server
директив в upstream {}
блоке.
Вес сервера
По умолчанию NGINX распределяет запросы между серверами в группе в соответствии с их весами, используя метод Round Robin. Параметр weight
директивы server
задает вес сервера; по умолчанию 1
:
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com;
server 192.0.0.1 backup;
}
В примере backend1.example.com имеет вес 5
; два других сервера имеют вес по умолчанию ( 1
), но тот, у которого есть IP-адрес 192.0.0.1
, помечается как backup
сервер и не получает запросы, если оба других сервера недоступны. При такой конфигурации весов все 6
запросы 5
отправляются на backend1.example.com и 1
на backend2.example.com .
Медленный старт сервера
Функция медленного старта сервера предотвращает перегрузку недавно восстановленного сервера соединениями, что может привести к истечению времени ожидания и повторной пометке сервера как неисправного.
В NGINX Plus медленный запуск позволяет вышестоящему серверу постепенно восстанавливать свой вес 0
до номинального значения после того, как он был восстановлен или стал доступным. Это можно сделать с помощью slow_start
параметра server
директивы:
upstream backend {
server backend1.example.com slow_start=30s;
server backend2.example.com;
server 192.0.0.1 backup;
}
Значение времени (здесь 30
секунды) задает время, в течение которого NGINX Plus увеличивает количество подключений к серверу до полного значения.
Обратите внимание, что если в группе есть только один сервер max_fails
, параметры директивы , fail_timeout
и игнорируются, и сервер никогда не считается недоступным.slow_start
server
Включение сохраняемости сеанса
Постоянство сеанса означает, что NGINX Plus идентифицирует сеансы пользователей и направляет все запросы в данном сеансе на один и тот же вышестоящий сервер.
NGINX Plus поддерживает три метода сохранения сеанса. Методы задаются sticky
директивой. (Для сохранения сеанса с NGINX с открытым исходным кодом используйте директиву hash
or , как описано выше .)ip_hash
Sticky cookie — NGINX Plus добавляет сеансовый cookie к первому ответу от вышестоящей группы и идентифицирует сервер, отправивший ответ. Следующий запрос клиента содержит значение cookie, и NGINX Plus направляет запрос на вышестоящий сервер, ответивший на первый запрос:
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky cookie srv_id expires=1h domain=.example.com path=/;
}
В примере srv_id
параметр задает имя файла cookie. Необязательный expires
параметр устанавливает время, в течение которого браузер сохраняет файл cookie (здесь 1
час). Необязательный domain
параметр определяет домен, для которого устанавливается файл cookie, а необязательный path
параметр определяет путь, для которого устанавливается файл cookie. Это самый простой метод сохранения сеанса.
Sticky route — NGINX Plus назначает «маршрут» клиенту при получении первого запроса. Все последующие запросы сравниваются с route
параметром server
директивы для идентификации сервера, на который проксируется запрос. Информация о маршруте берется либо из файла cookie, либо из URI запроса.
upstream backend {
server backend1.example.com route=a;
server backend2.example.com route=b;
sticky route $route_cookie $route_uri;
}
Метод прилипчивого обучения — NGINX Plus сначала находит идентификаторы сеансов, проверяя запросы и ответы. Затем NGINX Plus «узнает», какой восходящий сервер соответствует какому идентификатору сеанса. Как правило, эти идентификаторы передаются в файле cookie HTTP. Если запрос содержит уже «выученный» идентификатор сеанса, NGINX Plus перенаправляет запрос на соответствующий сервер:
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky learn
create=$upstream_cookie_examplecookie
lookup=$cookie_examplecookie
zone=client_sessions:1m
timeout=1h;
}
В примере один из вышестоящих серверов создает сеанс, устанавливая файл cookie EXAMPLECOOKIE
в ответе.
Обязательный create
параметр задает переменную, указывающую, как создается новый сеанс. В этом примере новые сеансы создаются из файла cookie EXAMPLECOOKIE
, отправленного вышестоящим сервером.
Обязательный lookup
параметр указывает, как искать существующие сеансы. В нашем примере существующие сеансы ищутся в файле cookie EXAMPLECOOKIE
, отправленном клиентом.
Обязательный zone
параметр указывает зону общей памяти, в которой хранится вся информация о закрепленных сессиях. В нашем примере зона называется client_sessions и имеет 1
размер в мегабайтах.
Это более сложный метод сохранения сеанса, чем два предыдущих, поскольку он не требует хранения файлов cookie на стороне клиента: вся информация хранится на стороне сервера в зоне общей памяти.
При наличии в кластере нескольких экземпляров NGINX, использующих метод «липкого обучения», возможна синхронизация содержимого их зон общей памяти при условии, что:
- зоны имеют одинаковое имя
- функциональность
zone_sync
настраивается на каждом экземпляре - параметр
sync
указан
Ограничение количества подключений
В NGINX Plus можно ограничить количество активных подключений к вышестоящему серверу, указав максимальное количество с помощью max_conns
параметра.
Если max_conns
предел достигнут, запрос помещается в очередь для дальнейшей обработки, при условии, что queue
также включена директива для установки максимального количества запросов, которые могут одновременно находиться в очереди:
upstream backend {
server backend1.example.com max_conns=3;
server backend2.example.com;
queue 100 timeout=70;
}
Если очередь заполнена запросами или вышестоящий сервер не может быть выбран в течение таймаута, заданного необязательным timeout
параметром, клиент получает ошибку.
Обратите внимание, что max_conns
ограничение игнорируется, если keepalive
в других worker processes
. В результате общее количество подключений к серверу может превышать max_conns
значение в конфигурации, в которой память совместно используется несколькими рабочими процессами .
Настройка проверок работоспособности
NGINX может постоянно тестировать вышестоящие HTTP-серверы, избегать отказавших серверов и корректно добавлять восстановленные серверы в группу с балансировкой нагрузки.
Инструкции по настройке проверки работоспособности для HTTP см. в разделе Проверки работоспособности HTTP.
Совместное использование данных с несколькими рабочими процессами
Если upstream
блок не включает zone
директиву, каждый рабочий процесс сохраняет свою собственную копию конфигурации группы серверов и поддерживает свой собственный набор связанных счетчиков. Счетчики включают текущее количество подключений к каждому серверу в группе и количество неудачных попыток передать запрос на сервер. В результате конфигурация группы серверов не может быть изменена динамически.
Когда zone
директива включена в upstream
блок, конфигурация вышестоящей группы хранится в области памяти, совместно используемой всеми рабочими процессами. Этот сценарий динамически настраивается, поскольку рабочие процессы получают доступ к одной и той же копии конфигурации группы и используют одни и те же связанные счетчики.
Эта zone
директива является обязательной для активных проверок работоспособности и динамической реконфигурации вышестоящей группы. Однако другие функции вышестоящих групп также могут выиграть от использования этой директивы.
Например, если конфигурация группы не используется совместно, каждый рабочий процесс поддерживает собственный счетчик неудачных попыток передать запрос на сервер (устанавливается параметром max_fails ). В этом случае каждый запрос попадает только к одному рабочему процессу. Когда рабочий процесс, выбранный для обработки запроса, не может передать запрос на сервер, другие рабочие процессы ничего об этом не знают. В то время как некоторые рабочие процессы могут считать сервер недоступным, другие могут по-прежнему отправлять запросы на этот сервер. Чтобы сервер окончательно считался недоступным, количество неудачных попыток за время, заданное fail_timeout
параметром, должно быть равно max_fails
произведению на количество рабочих процессов. С другой стороны, zone
директива гарантирует ожидаемое поведение.
Точно так же метод балансировки нагрузки Least Connections может не работать должным образом без zone
директивы, по крайней мере, при низкой нагрузке. Этот метод передает запрос на сервер с наименьшим количеством активных подключений. Если конфигурация группы не используется совместно, каждый рабочий процесс использует собственный счетчик количества подключений и может отправить запрос на тот же сервер, на который только что отправил запрос другой рабочий процесс. Однако вы можете увеличить количество запросов, чтобы уменьшить этот эффект. При высокой нагрузке запросы распределяются между рабочими процессами равномерно, и Least Connections
метод работает как положено.
Установка размера зоны
Невозможно порекомендовать идеальный размер зоны памяти, поскольку модели использования сильно различаются. Требуемый объем памяти определяется тем, какие функции (такие как сохранение сеанса , проверки работоспособности или повторное разрешение DNS ) включены, а также тем, как идентифицируются вышестоящие серверы.
Например, при использовании sticky_route
метода сохранения сеанса и включенной одиночной проверки работоспособности зона размером 256 КБ может вместить информацию об указанном количестве вышестоящих серверов:
- 128 серверов (каждый определяется как пара IP-адрес:порт)
- 88 серверов (каждый определяется как пара имя хоста: порт, где имя хоста разрешается в один IP-адрес)
- 12 серверов (каждый определяется как пара имя хоста: порт, где имя хоста разрешается в несколько IP-адресов)
Настройка балансировки нагрузки HTTP с использованием DNS
Конфигурацию группы серверов можно изменить во время выполнения с помощью DNS.
Для серверов в вышестоящей группе, которые идентифицируются доменным именем в server
директиве, NGINX Plus может отслеживать изменения в списке IP-адресов в соответствующей записи DNS и автоматически применять изменения для балансировки нагрузки для вышестоящей группы, не требуя запустить снова. Это можно сделать, включив resolver
директиву в http
блок вместе с resolve
параметром к server
директиве:
http {
resolver 10.0.0.1 valid=300s ipv6=off;
resolver_timeout 10s;
server {
location / {
proxy_pass http://backend;
}
}
upstream backend {
zone backend 32k;
least_conn;
# ...
server backend1.example.com resolve;
server backend2.example.com resolve;
}
}
В этом примере resolve
параметр server
директивы указывает NGINX Plus периодически переопределять доменные имена backend1.example.com и backend2.example.com в IP-адреса.
Директива resolver
определяет IP-адрес DNS-сервера, на который NGINX Plus отправляет запросы (здесь 10.0.0.1
). По умолчанию NGINX Plus повторно разрешает записи DNS с частотой, указанной временем жизни (TTL) в записи, но вы можете переопределить значение TTL с помощью valid
параметра; в примере это 300
секунды или 5
минуты.
Необязательный ipv6=off
параметр означает, что для балансировки нагрузки используются только адреса IPv4, хотя по умолчанию поддерживается разрешение как адресов IPv4, так и IPv6.
Если доменное имя разрешается в несколько IP-адресов, адреса сохраняются в вышестоящей конфигурации и распределяются по нагрузке. В нашем примере нагрузка на серверы распределяется по методу балансировки нагрузки с наименьшим количеством подключений . Если список IP-адресов для сервера изменился, NGINX Plus немедленно начинает балансировку нагрузки по новому набору адресов.
Балансировка нагрузки серверов Microsoft Exchange
В NGINX Plus R7 и более поздних версиях NGINX Plus может проксировать трафик Microsoft Exchange на сервер или группу серверов и балансировать нагрузку.
Чтобы настроить балансировку нагрузки серверов Microsoft Exchange:
В location
блоке настройте проксирование к вышестоящей группе серверов Microsoft Exchange proxy_pass
директивой:
location / {
proxy_pass https://exchange;
# ...
}
Чтобы соединения Microsoft Exchange проходили на вышестоящие серверы, в location
блоке установите proxy_http_version
значение директивы в 1.1
, а proxy_set_header
директиву в Connection ""
, как и для keepalive-соединения:
location / {
# ...
proxy_http_version 1.1;
proxy_set_header Connection "";
# ...
}
В http
блоке настройте вышестоящую группу серверов Microsoft Exchange с upstream
блоком с тем же именем, что и вышестоящая группа, указанная в proxy_pass
директиве на шаге 1. Затем укажите ntlm
директиву, чтобы разрешить серверам в группе принимать запросы с проверкой подлинности NTLM:
http {
# ...
upstream exchange {
zone exchange 64k;
ntlm;
# ...
}
}
Добавьте серверы Microsoft Exchange в вышестоящую группу и при необходимости укажите метод балансировки нагрузки :
http {
# ...
upstream exchange {
zone exchange 64k;
ntlm;
server exchange1.example.com;
server exchange2.example.com;
# ...
}
}
Полный пример NTLM
http {
# ...
upstream exchange {
zone exchange 64k;
ntlm;
server exchange1.example.com;
server exchange2.example.com;
}
server {
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/company.com.crt;
ssl_certificate_key /etc/nginx/ssl/company.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_pass https://exchange;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
}
Дополнительные сведения о настройке Microsoft Exchange и NGINX Plus см . в руководстве по развертыванию балансировки нагрузки на серверы Microsoft Exchange с NGINX Plus .
Динамическая конфигурация с использованием API NGINX Plus
В NGINX Plus конфигурация группы вышестоящих серверов может динамически изменяться с помощью API NGINX Plus. Команду конфигурации можно использовать для просмотра всех серверов или определенного сервера в группе, изменения параметра для определенного сервера и добавления или удаления серверов. Дополнительные сведения и инструкции см. в разделе Настройка динамической балансировки нагрузки с помощью API NGINX Plus .
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.