Nginx как балансировщик нагрузки: настройка и конфигурация

14.10.2026
0
6
---

Nginx — это не только веб-сервер и обратный прокси-сервер, но и эффективный инструмент для балансировки нагрузки между несколькими серверами. С его помощью можно распределять входящие HTTP-запросы между несколькими бэкендами, повышать производительность веб-приложения и снижать риск простоя сервиса при отказе одного из серверов.

Балансировка нагрузки с помощью nginx особенно актуальна для высоконагруженных сайтов, API, интернет-магазинов и других веб-проектов, которым необходимо обрабатывать большое количество одновременных запросов.

Основные задачи балансировщика нагрузки nginx:

  • распределение запросов между несколькими серверами;
  • увеличение пропускной способности веб-приложения;
  • снижение нагрузки на отдельные бэкенды;
  • повышение доступности сервиса при отказе части серверов;
  • управление соединениями и временем ожидания ответа;
  • возможность масштабирования инфраструктуры без изменения адреса сервиса для клиентов.

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

Для примера будем использовать три веб-сервера, работающих на порту 8080:

  • 10.32.18.6:8080;
  • 10.32.18.7:8080;
  • 10.32.18.8:8080.

Nginx будет принимать входящие запросы и перенаправлять их на доступные бэкенды. Если один из серверов перестанет принимать соединения, балансировщик сможет временно исключить его из обработки запросов при соблюдении условий пассивного контроля доступности.

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

Также необходимо учитывать различия между бесплатной версией Nginx Open Source и коммерческой платформой NGINX Plus. В частности, возможности активных проверок состояния бэкендов и расширенного мониторинга зависят от используемой редакции и доступных модулей.

2. Добавление бэкендов в конфигурацию nginx

Чтобы настроить nginx в качестве балансировщика нагрузки, необходимо определить группу серверов, между которыми будут распределяться запросы. Для этого используется директива upstream из модуля ngx_http_upstream_module.

Добавим в конфигурацию следующую группу бэкендов:

upstream cache_api {    server 10.32.18.6:8080;    server 10.32.18.7:8080;    server 10.32.18.8:8080;}

В данном примере группа cache_api включает три сервера с одинаковым весом. По умолчанию nginx использует алгоритм Round Robin, который распределяет запросы между серверами с учётом заданных весов.

Обратите внимание: в имени группы upstream лучше использовать символ подчёркивания вместо дефиса, чтобы избежать проблем с интерпретацией переменных nginx.

Теперь настроим обратное проксирование запросов в виртуальном хосте:

server {    listen 80;    server_name example.com;    location / {        proxy_pass http://cache_api;        proxy_set_header Host $host;        proxy_set_header X-Real-IP $remote_addr;        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_set_header X-Forwarded-Proto $scheme;    }}

В этой конфигурации nginx принимает HTTP-запросы на порту 80 и передаёт их одному из серверов группы cache_api.

Заголовки X-Real-IP и X-Forwarded-For позволяют передать приложению информацию об IP-адресе клиента. Заголовок X-Forwarded-Proto сообщает исходную схему запроса — HTTP или HTTPS.

Если балансировщик находится за другим прокси-сервером или CDN, необходимо отдельно настроить доверие к передаваемым IP-заголовкам. Без такой настройки данные об исходном клиенте могут быть недостоверными.

Основные параметры настройки бэкендов

Для управления распределением нагрузки и поведением балансировщика используются следующие параметры.

weight — вес сервера. По умолчанию равен 1. Сервер с большим весом получает пропорционально большую долю запросов при использовании алгоритмов, учитывающих вес.

max_conns — максимальное количество активных соединений к серверу. Значение 0 означает отсутствие установленного ограничения. Фактическое поведение также зависит от конфигурации рабочих процессов и общей архитектуры соединений nginx.

max_fails — количество неудачных попыток взаимодействия с сервером, после которого он считается временно недоступным. По умолчанию значение равно 1.

fail_timeout — интервал, в течение которого учитываются неудачные попытки, а также период временного исключения сервера из балансировки. По умолчанию составляет 10 секунд.

backup — обозначает резервный сервер, который используется, когда основные серверы группы недоступны. Этот параметр не поддерживается для группы, в которой применяется hash или ip_hash.

down — помечает сервер как недоступный для балансировки. Обычно используется при ручном выводе сервера из эксплуатации.

Рассмотрим пример конфигурации с обработкой ошибок соединения:

upstream cache_api {    server 10.32.18.6:8080 max_fails=2 fail_timeout=10s;    server 10.32.18.7:8080 max_fails=2 fail_timeout=10s;    server 10.32.18.8:8080 max_fails=2 fail_timeout=10s;}

При таких настройках две неудачные попытки в пределах десятисекундного интервала могут привести к временному исключению сервера из балансировки на 10 секунд.

При этом важно понимать, что пассивная проверка доступности не является полноценным мониторингом приложения. Конкретное поведение зависит от типа ошибки, способа обработки запроса и версии nginx.

3. Основные алгоритмы балансировки нагрузки nginx

Nginx поддерживает несколько алгоритмов распределения запросов. Выбор подходящего метода зависит от характера нагрузки, длительности запросов, состояния серверов и требований к сохранению клиентских сессий.

Round Robin — распределение по очереди

Round Robin используется по умолчанию. Балансировщик распределяет запросы между серверами по очереди, учитывая их веса.

upstream cache_api {    server 10.32.18.6:8080;    server 10.32.18.7:8080;    server 10.32.18.8:8080;}

Этот алгоритм подходит для большинства стандартных веб-приложений, если серверы обладают сопоставимой производительностью.

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

Least Connections — минимальное количество соединений

Алгоритм Least Connections направляет новый запрос на сервер с наименьшим количеством активных соединений с учётом весов серверов.

Для его включения используется директива least_conn:

upstream cache_api {    least_conn;    server 10.32.18.6:8080;    server 10.32.18.7:8080;    server 10.32.18.8:8080;}

Этот вариант полезен, если запросы имеют разную продолжительность обработки. Например, один сервер может выполнять длительные операции API, а другой — быстро отдавать статические данные или простые ответы.

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

IP Hash — привязка клиента к серверу

Алгоритм ip_hash использует IP-адрес клиента для выбора сервера. Это позволяет при определённых условиях направлять запросы одного клиента на один и тот же бэкенд.

upstream cache_api {    ip_hash;    server 10.32.18.6:8080;    server 10.32.18.7:8080;    server 10.32.18.8:8080;}

Такой подход может быть полезен для приложений, которые хранят пользовательское состояние локально на сервере.

Но IP Hash не заменяет полноценное хранение сессий. Если множество пользователей выходят в интернет через один NAT-шлюз или прокси, распределение может оказаться неравномерным. Кроме того, изменение доступности бэкендов способно изменить соответствие клиента серверу.

Для масштабируемых приложений предпочтительнее хранить сессии в общем хранилище или использовать другой механизм управления состоянием.

Hash — балансировка по заданному ключу

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

upstream cache_api {    hash $request_uri consistent;    server 10.32.18.6:8080;    server 10.32.18.7:8080;    server 10.32.18.8:8080;}

В этом примере используется URI запроса. Один и тот же URI обычно соответствует одному и тому же серверу, пока состав группы и её состояние остаются совместимыми с выбранным алгоритмом.

Параметр consistent включает согласованное хеширование, которое помогает уменьшить количество ключей, переназначаемых другим серверам при изменении состава группы.

Этот метод подходит для сценариев, где желательно сохранять привязку определённых запросов к конкретным бэкендам.

Random — случайное распределение

Алгоритм random выбирает сервер случайным образом с учётом его веса.

upstream cache_api {    random;    server 10.32.18.6:8080;    server 10.32.18.7:8080;    server 10.32.18.8:8080;}

Также можно использовать комбинацию random two least_conn, при которой nginx выбирает два сервера случайным образом, а затем направляет запрос на сервер с меньшим количеством активных соединений.

upstream cache_api {    random two least_conn;    server 10.32.18.6:8080;    server 10.32.18.7:8080;    server 10.32.18.8:8080;}

Какой алгоритм балансировки выбрать

Для типового веб-приложения чаще всего достаточно Round Robin. Если запросы обрабатываются неравномерно по времени, стоит рассмотреть Least Connections. Для привязки запросов к серверу можно использовать IP Hash или Hash, однако в таких случаях важно учитывать ограничения выбранного механизма.

В NGINX Plus также доступны дополнительные алгоритмы, включая least_time, который учитывает время обработки запросов и состояние соединений. Эта возможность не относится к стандартным алгоритмам бесплатной версии Nginx Open Source.

4. Проблемы балансировки нагрузки nginx

Настройка балансировщика — это только часть работы по масштабированию веб-приложения. Чтобы распределение нагрузки действительно повысило отказоустойчивость, необходимо подготовить само приложение, базу данных, сетевую инфраструктуру и механизмы хранения состояния.

Обнаружение неисправных бэкендов

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

Предположим, один из бэкендов перегружен и начинает возвращать ошибки HTTP 500 или 502. При этом соединение с ним устанавливается успешно.

Пассивная проверка доступности в nginx Open Source не выполняет полноценную независимую проверку работоспособности приложения. Сервер может оставаться доступным на сетевом уровне, но не выполнять бизнес-операции корректно.

При стандартной конфигурации nginx не исключает бэкенд автоматически только потому, что тот вернул HTTP 500 или 502. Для обработки отдельных кодов ответа необходимо дополнительно настраивать параметры proxy_next_upstream и учитывать условия повторной попытки.

Например:

location / {    proxy_pass http://cache_api;    proxy_next_upstream error timeout http_500 http_502 http_503 http_504;    proxy_next_upstream_tries 3;}

Такая настройка разрешает повторную попытку на другом сервере при указанных ошибках, если условия повторного проксирования соблюдены.

Следует учитывать, что повторная отправка запроса может быть небезопасна для некоторых операций, например для создания заказа или списания средств. Для таких запросов требуется отдельно продумать идемпотентность и защиту от дублирования операций.

Активные и пассивные проверки состояния

В бесплатной версии nginx доступен механизм пассивного контроля: балансировщик учитывает неудачные взаимодействия с сервером во время обработки реальных запросов.

NGINX Plus предоставляет расширенные возможности активных проверок состояния бэкендов. С их помощью можно отправлять специальные контрольные запросы и оценивать доступность приложения независимо от пользовательского трафика.

Для сложных инфраструктур также можно использовать внешние системы мониторинга, которые проверяют HTTP-статусы, время ответа, доступность базы данных и другие показатели.

При выборе решения необходимо учитывать, что проверка доступности порта не равнозначна проверке работоспособности приложения. Надёжный health check должен проверять именно те компоненты, от которых зависит предоставление услуги.

Настройка таймаутов проксирования

Таймауты определяют, сколько времени nginx будет ожидать установления соединения или получения данных от бэкенда.

Основные параметры:

  • proxy_connect_timeout — максимальное время установления соединения с сервером;
  • proxy_read_timeout — максимальный интервал между операциями чтения данных от сервера;
  • proxy_send_timeout — максимальный интервал между операциями записи данных на сервер.

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

location / {    proxy_pass http://cache_api;    proxy_connect_timeout 3s;    proxy_send_timeout 30s;    proxy_read_timeout 30s;}

Значения необходимо подбирать с учётом приложения. Слишком большие таймауты могут приводить к накоплению долгоживущих запросов, а слишком маленькие — к преждевременному завершению корректных операций.

Важно: proxy_read_timeout и proxy_send_timeout обычно задают максимальный интервал между последовательными операциями чтения или записи, а не общий срок выполнения запроса.

Другие важные особенности балансировки

При распределении нагрузки между несколькими серверами необходимо учитывать следующие факторы:

  • Состояние приложения. Все бэкенды должны иметь совместимые версии приложения и одинаковые настройки.
  • Хранение сессий. Локальные сессии могут нарушать работу при переключении клиента на другой сервер.
  • База данных. Если все бэкенды используют одну перегруженную базу данных, добавление новых серверов приложения не обязательно повысит производительность.
  • TLS и HTTPS. Необходимо правильно настроить завершение TLS-соединения и передачу информации об исходном протоколе.
  • Повторные запросы. Автоматические повторы могут увеличить нагрузку на оставшиеся серверы и привести к дублированию операций.
  • Мониторинг. Следует отслеживать количество запросов, ошибки, задержки ответа и состояние каждого бэкенда.

5. Полный пример конфигурации nginx load balancer

Ниже приведён пример конфигурации nginx, которая объединяет группу бэкендов, балансировку нагрузки, проксирование запросов и расширенное логирование.

Файл можно использовать как основу для настройки отдельного виртуального хоста, предварительно адаптировав его к структуре конфигурации конкретного сервера.

http {    log_format upstream_log        '$remote_addr - $host [$time_local] "$request" '        'request_length=$request_length '        'status=$status bytes_sent=$bytes_sent '        'body_bytes_sent=$body_bytes_sent '        'referer="$http_referer" '        'user_agent="$http_user_agent" '        'upstream_addr="$upstream_addr" '        'upstream_status="$upstream_status" '        'request_time=$request_time '        'upstream_response_time="$upstream_response_time" '        'upstream_connect_time="$upstream_connect_time" '        'upstream_header_time="$upstream_header_time"';    upstream cache_api {        least_conn;        server 10.32.18.6:8080 max_fails=2 fail_timeout=10s;        server 10.32.18.7:8080 max_fails=2 fail_timeout=10s;        server 10.32.18.8:8080 max_fails=2 fail_timeout=10s;        keepalive 32;    }    server {        listen 80;        server_name example.com;        access_log /var/log/nginx/cache_api_access.log upstream_log;        error_log /var/log/nginx/cache_api_error.log warn;        location / {            proxy_pass http://cache_api;            proxy_http_version 1.1;            proxy_set_header Connection "";            proxy_set_header Host $host;            proxy_set_header X-Real-IP $remote_addr;            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;            proxy_set_header X-Forwarded-Proto $scheme;            proxy_connect_timeout 3s;            proxy_send_timeout 30s;            proxy_read_timeout 30s;            proxy_next_upstream error timeout http_502 http_503 http_504;            proxy_next_upstream_tries 3;        }    }}

Важные замечания по конфигурации:

  1. Блок http должен находиться в основном конфигурационном файле nginx или подключаемом файле, где разрешён контекст http. Если вы редактируете конфигурацию отдельного виртуального хоста внутри sites-enabled, обычно нужно добавлять только блоки upstream и server в соответствующие контексты, а не создавать ещё один http.
  2. least_conn выбран для примера. Если все запросы примерно одинаковы по длительности, можно использовать стандартный Round Robin.
  3. keepalive 32 задаёт количество кэшируемых неактивных upstream-соединений на один рабочий процесс. Для повторного использования соединений применяются proxy_http_version 1.1 и очистка заголовка Connection.
  4. Параметры повторного проксирования следует подбирать под особенности приложения и типы запросов.
  5. Пути к логам, доменное имя и адреса серверов необходимо заменить на реальные значения инфраструктуры.

Проверка конфигурации nginx

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

nginx -t

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

systemctl reload nginx

Для проверки доступности бэкендов можно выполнить запросы непосредственно к каждому серверу:

curl -I http://10.32.18.6:8080/curl -I http://10.32.18.7:8080/curl -I http://10.32.18.8:8080/

Проверить работу балансировщика можно запросом к его внешнему адресу:

curl -I http://example.com/

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

6. Мониторинг и диагностика балансировки

Одной настройки балансировщика недостаточно. Чтобы своевременно обнаруживать проблемы, необходимо анализировать логи nginx и метрики приложения.

В приведённой конфигурации используется отдельный формат логирования, который содержит следующие параметры:

  • upstream_addr — адрес сервера, на который был отправлен запрос;
  • upstream_status — HTTP-статус, полученный от бэкенда;
  • request_time — общее время обработки запроса на стороне nginx;
  • upstream_connect_time — время установления соединения с бэкендом;
  • upstream_header_time — время до получения заголовков ответа;
  • upstream_response_time — время получения ответа от бэкенда.

Эти параметры позволяют выявлять медленные серверы, ошибки проксирования и проблемы с установлением соединений.

Например, если время подключения к бэкенду постоянно увеличивается, стоит проверить сетевую доступность сервера и его текущую нагрузку. Если соединение устанавливается быстро, но время ответа остаётся высоким, необходимо исследовать приложение, базу данных и внешние зависимости.

При повторных попытках проксирования некоторые поля логов могут содержать несколько значений, соответствующих разным upstream-серверам. Это полезно при диагностике ошибок и анализе переключений между бэкендами.

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

7. Заключение

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

Для базовой настройки достаточно определить группу upstream и направить на неё запросы через proxy_pass. При необходимости можно выбрать другой алгоритм балансировки, настроить веса серверов, ограничить количество соединений, определить таймауты и организовать логирование.

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

Для большинства стандартных проектов возможностей Nginx Open Source достаточно, чтобы организовать эффективное распределение HTTP-запросов. Если требуются активные проверки состояния серверов и дополнительные возможности управления балансировкой, стоит рассмотреть NGINX Plus или интеграцию с внешними системами мониторинга.

Правильно настроенный nginx load balancer помогает масштабировать веб-приложение, эффективнее использовать серверные ресурсы и создавать инфраструктуру, готовую к росту нагрузки.

Понравиласть статья? Жми лайк или расскажи своим друзьям!
Теги к новости:
Nginx, System Administrator
Комментарии
Добавить комментарий
Добавление комментария
Ваше Имя:
Ваш E-Mail:
Это код:
Кликните на изображение чтобы обновить код, если он неразборчив
Введите сюда: