Содержание

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

Разберём, как работают балансировщики, какие бывают алгоритмы, как подготовить приложение и как не сделать сам балансировщик единой точкой отказа.

Зачем нужен балансировщик нагрузки?

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

Что даёт балансировка:

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

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

Балансировщики работают на транспортном уровне (L4) — распределяют TCP-соединения, не заглядывая внутрь, — или на прикладном (L7) — понимают HTTP и могут направлять запросы по адресу, заголовкам и cookies. Для веб-приложений обычно используют L7.

Алгоритм Как работает Когда подходит
Round robin По очереди на каждый сервер Одинаковые серверы и запросы
Взвешенный round robin Мощным серверам — больше запросов Серверы разной мощности
Least connections На сервер с наименьшим числом соединений Запросы разной длительности
Хеш по IP или ключу Один клиент — всегда на один сервер Когда нужна привязка, например для кеша

Рисунок: человек несёт грузы на коромысле Фото: Unsplash

Как работают проверки здоровья?

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

upstream app {
    least_conn;
    server 10.0.0.11:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.12:8080 max_fails=3 fail_timeout=30s;
    server 10.0.0.13:8080 backup;
}

server {
    listen 443 ssl;
    http2 on;
    location / {
        proxy_pass http://app;
        proxy_next_upstream error timeout http_502 http_503;
    }
}

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

Как подготовить приложение к нескольким серверам?

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

  1. Сессии — в Redis или базе данных, а не в файлах сервера.
  2. Загруженные файлы — в объектном хранилище, подробнее в статье загрузка и хранение файлов.
  3. Кеш и блокировки — в общем Redis, статья Redis в веб-проекте.
  4. Задачи по расписанию — запускаются на одном сервере или с распределённой блокировкой, иначе выполнятся несколько раз.
  5. Логи — собираются централизованно, а не лежат на каждом сервере.
  6. Реальный IP клиента — передаётся балансировщиком в заголовке и правильно читается приложением.

Как не сделать балансировщик единой точкой отказа?

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

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

Про выбор инфраструктуры — статьи VPS, облако или managed-сервисы и нужен ли Kubernetes.

Коротко

  • Балансировщик распределяет запросы между серверами и исключает сломанные.
  • Для веба обычно используют L7-балансировку и алгоритм least connections или round robin.
  • Проверки здоровья должны проверять готовность приложения, а не только живой процесс.
  • Приложение должно быть stateless: сессии, файлы и кеш — в общих хранилищах.
  • Резервируйте и сам балансировщик, иначе он станет единой точкой отказа.

Частые вопросы

  • Сколько серверов нужно для отказоустойчивости?

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

  • Чем балансировщик отличается от CDN?

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

  • Нужен ли Kubernetes для балансировки?

    Нет. Для нескольких серверов хватает Nginx, HAProxy или облачного балансировщика. Kubernetes добавляет балансировку автоматически, но он оправдан при большом количестве сервисов.