Хостинг SpaceWeb
Серверы Дизайн Сайты Безопасность Домены PHP Кейсы клиентов

Балансировка нагрузки с помощью Nginx

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

Что такое балансировка нагрузки

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

Представьте веб‑сервис с тысячами пользователей. Если все запросы пойдут на один сервер, он быстро исчерпает ресурсы — закончится память, загрузится процессор или превысится лимит сетевых соединений. В итоге сайт начнёт тормозить, выдавать ошибки или вообще перестанет открываться.

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

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

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

Nginx удобен в этой роли по нескольким причинам:

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

Что такое upstream в Nginx

upstream в Nginx — это блок конфигурации, в котором задаётся группа backend-серверов, между которыми затем распределяются запросы.

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

Upstream нужен, чтобы:

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

Методы балансировки нагрузки

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

Round Robin

Round Robin — самый простой способ балансировки. Запросы передаются серверам последовательно: первый — на один узел, второй — на следующий, затем на третий, после чего цикл начинается заново. Если в пуле только два backend-сервера, нагрузка будет распределяться между ними поочерёдно.

Пример конфигурации:

upstream backend_pool {
    server 192.168.10.21:8080;
    server 192.168.10.22:8080;
}

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

Схема простая, но у неё есть минус: алгоритм не учитывает, насколько загружены серверы.

Round Robin с весами

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

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

Пример:

upstream backend_pool {
    server 192.168.10.31:9000 weight=4;
    server 192.168.10.32:9000 weight=2;
    server 192.168.10.33:9000 weight=1;
}

В этой конфигурации больше всего запросов получит сервер 192.168.10.31:9000, потому что его вес выше остальных.

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

Least Connection

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

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

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

upstream app_nodes {
    least_conn;
    server 172.16.5.11:8081;
    server 172.16.5.12:8081;
    server 172.16.5.13:8081;
}

В такой конфигурации Nginx будет выбирать сервер с наименьшим числом активных подключений.

Least Connection с весами

Этот алгоритм тоже можно комбинировать с весами. Тогда Nginx будет учитывать не только число текущих соединений, но и приоритет сервера внутри пула.

Пример:

upstream app_nodes {
    least_conn;
    server 10.0.2.41:8080 weight=3;
    server 10.0.2.42:8080 weight=2;
    server 10.0.2.43:8080 weight=1;
}

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

IP Hash

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

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

upstream sticky_backend {
    ip_hash;
    server 192.168.50.101:8080;
    server 192.168.50.102:8080;
}

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

Но у метода есть минусы. Он не учитывает ни фактическую загрузку серверов, ни их производительность.

Таблица сравнения методов нагрузки в Nginx

Метод Как работает Плюсы Минусы
Round Robin Последовательно распределяет запросы между серверами по кругу Прост в настройке; подходит для базовых схем балансировки; хорошо работает, если все серверы примерно одинаковы по мощности Не учитывает текущую загрузку узлов; может работать неэффективно в неоднородной инфраструктуре
Round Robin с весами Распределяет запросы по кругу, но с учётом заданных весов Позволяет направлять больше запросов на более мощные серверы; удобен для пулов с разной производительностью узлов Веса приходится задавать вручную; не учитывает реальную загрузку серверов в моменте
Least Connection Отправляет новый запрос на тот сервер, у которого сейчас меньше активных соединений Лучше распределяет нагрузку при большом числе одновременных подключений; подходит для сценариев, где запросы сильно различаются по длительности; помогает снизить перегрузку отдельных узлов Количество соединений не всегда точно отражает реальную нагрузку; без дополнительных параметров не учитывает разницу в мощности серверов
Least Connection с весами Выбирает сервер с учётом числа активных соединений и назначенного веса Сочетает преимущества весов и динамического распределения; подходит для серверов с разной производительностью Веса всё равно приходится подбирать вручную; не всегда просто сразу найти оптимальный баланс
IP Hash Определяет сервер на основе IP-адреса клиента, поэтому запросы одного пользователя обычно попадают на один и тот же backend Сохраняет привязку клиента к конкретному серверу; удобен для приложений, чувствительных к сессиям Не учитывает текущую загрузку серверов; может распределять трафик неравномерно; хуже подходит для сетей с большим числом пользователей за одним IP

Проверка доступности серверов

Проверка доступности серверов (health check) помогает балансировщику понять, какие серверы готовы принимать запросы, а какие — нет. Если сервер зависает или выдаёт ошибки, трафик на него не отправляют — так пользователи не получают ошибок. В Nginx это особенно важно при работе с несколькими серверами: даже если один из них выйдет из строя, сервис продолжит работать.

В Nginx используют два подхода к health check:

В Nginx Open Source по умолчанию работает пассивная проверка серверов через параметры max_fails и fail_timeout в блоке upstream.

max_fails задаёт число допустимых неудачных попыток соединения (по умолчанию — 1; при значении 0 проверка отключается). fail_timeout определяет период учёта ошибок и время, на которое сервер отключают при их превышении.

Если сервер не отвечает нужное число раз за заданный период, Nginx временно перестаёт направлять на него запросы — до истечения fail_timeout. Так система работает стабильнее и выдаёт меньше ошибок.

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

upstream backend_pool {
    server 10.10.1.21:8080 max_fails=2 fail_timeout=15s;
    server 10.10.1.22:8080 max_fails=2 fail_timeout=15s;
    server 10.10.1.23:8080 backup;
}

При такой конфигурации Nginx временно перестаёт направлять запросы на сервер, если тот несколько раз подряд не ответил в пределах интервала fail_timeout. По истечении этого времени сервер не подключается автоматически — система начинает проверять его на реальном пользовательском трафике. Если ответы стабильны, сервер снова включается в балансировку.

На практике health check нужен сразу для нескольких задач, чтобы:

Проверка доступности серверов — ключевой элемент отказоустойчивой балансировки. Без неё часть запросов может уходить на неработающий сервер, из‑за чего пользователи получают ошибки, а польза от балансировки теряется.

Пример полной конфигурации балансировки в Nginx

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

http {
    upstream app_backend {
        server 192.168.1.101:8080 max_fails=3 fail_timeout=20s;
        server 192.168.1.102:8080 max_fails=3 fail_timeout=20s;
    }

    server {
        listen 80;
        server_name example.ru;

        location / {
            proxy_pass http://app_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;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

Как работает эта конфигурация:

Параметры max_fails=3 fail_timeout=20s в примере нужны для пассивной проверки доступности. Если один из серверов несколько раз не ответит за указанный интервал, Nginx временно перестанет направлять на него трафик.

Где используется балансировка нагрузки

Балансировка нагрузки нужна, когда один сервер не справляется с запросами или важно сохранить работу сервиса при сбоях. Она помогает распределить трафик между серверами — так система работает быстрее и надёжнее.

Чаще всего балансировку нагрузки используют:

Таким образом, балансировка нагрузки полезна не только крупным сервисам: она помогает любым проектам распределять трафик, избегать перегрузок и оставаться доступными — даже при росте нагрузки или сбоях.

Заключение

Настроив балансировку нагрузки в Nginx, вы делаете важный шаг к созданию надёжной и масштабируемой инфраструктуры. Описанные в статье методы легко адаптировать под реальные задачи.

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

Блок FAQ

Что такое upstream в Nginx?

upstream в Nginx — это блок конфигурации, в котором объединяют несколько backend-серверов в одну группу для проксирования и балансировки нагрузки.

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

В Nginx чаще всего используют Round Robin, Weighted Round Robin, Least Connection, Weighted Least Connection и IP Hash. Они отличаются тем, что могут распределять запросы по очереди, с учётом весов, по числу активных соединений или с привязкой клиента к одному серверу.

Чем round robin отличается от ip hash?

Round Robin распределяет запросы по очереди между всеми серверами, а IP Hash направляет запросы одного и того же клиента на один и тот же backend-сервер по его IP-адресу.

Можно ли использовать Nginx как load balancer?

Да, Nginx можно использовать как балансировщик нагрузки: он принимает входящие запросы и распределяет их между несколькими backend-серверами.

Перейти на оригинал