HAProxy обратный прокси: где схема ломается под нагрузкой
Обратный прокси стоит первым в схеме и первым принимает последствия: пока трафик умеренный, конфигурация из десятка строк держит нагрузку незаметно. Ломается она там, где всплеск запросов или отказ узла приложения превращают прокси в точку отказа прокси для всего сервиса — пропадает вход, а не отдельная функция.
Переполнение соединений проявляется раньше остального. Очередь на фронтенде рассчитана на спокойный поток: при залпе свободные слоты заканчиваются, часть клиентов получает обрыв вместо ответа, а бэкенд, способный их обработать, простаивает. Деградация под нагрузкой идёт нелинейно — время ответа растёт скачком, потому что новые запросы встают в одну очередь со старыми и ждут вместе с ними.
Второе узкое место схемы — отсутствие проверок работоспособности узлов. Без периодического опроса балансировщик продолжает слать трафик туда, где приложение уже отдаёт ошибки, и отказ узла приложения тянет за собой весь сервис целиком. Рядом ещё одна типовая причина: ручные правки конфигурации без отката, когда перезагрузка идёт без проверки синтаксиса и без сохранённой предыдущей версии, — и в момент аварии инженер остаётся без пути назад.
Все три сценария закрываются на уровне схемы и правил, а не героическими действиями во время сбоя. Ниже разбираем, как именно: лимиты и таймауты под реальный профиль трафика, проверки состояния с выводом узла из ротации, безопасное применение изменений с сохранением предыдущей версии и быстрым возвратом к ней.
Что даёт управляемый балансировщик: устойчивость и предсказуемость
Отказ узла перестаёт быть событием для пользователя. Балансировщик на HAProxy опрашивает серверы приложений по заданному интервалу и с порогами rise/fall выводит отказавший из пула раньше, чем клиент получит ошибку, а резервный узел принимает нагрузку сам. Время восстановления измеряется секундами и больше не зависит от того, кто первым заметил проблему — дежурный или система мониторинга.
Пропускная способность растёт на том же оборудовании. Переиспользование соединений к серверам и балансировка по числу активных запросов убирают перекос, когда один узел держит больше клиентов, чем остальные; повторное использование защищённых сессий сокращает накладные расходы на установку связи.
Уходит целый класс отказов, связанных с ручным вмешательством: выкатка новой версии идёт через плавный вывод узла из ротации, а не через остановку сервиса, а неудачные запросы к повторяемым операциям уходят на живой узел. Правила закрепления сессии задаются явно, поэтому «плавающие» ошибки авторизации, которые иначе ищут неделями, не возникают вовсе.
Появляется прозрачный журнал событий: единый формат записи фиксирует время отклика по каждому серверу, коды ответов и то, какой узел обслужил запрос. По нему сразу видно, где деградация — в приложении или на пути до него, — а предсказуемость отклика перестаёт быть предметом догадок: 95-й процентиль держится в узком коридоре и на пиковой нагрузке.
Режимы работы прокси и балансировки: что выбрать под задачу
Режим работы прокси определяет, что вообще доступно на точке входа: видно ли только адрес и порт или ещё и заголовки, путь, домен. От этого зависят маршрутизация по содержимому, терминация шифрования и то, на каком уровне считаются проверки работоспособности.
Четыре варианта, между которыми реально выбирают:
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Прямой проход на уровне соединений | Нестандартные протоколы, базы данных, сквозное шифрование до сервера | Содержимое запроса закрыто: ни маршрутизации по пути, ни правки заголовков; проверка — только доступность порта |
| Терминация шифрования на точке входа | Веб-сервисы с общим доменом, единый сертификат, переиспользование соединений | Ключ лежит на прокси; внутренний участок без повторного шифрования требует доверенной сети |
| Маршрутизация по содержимому | Несколько сервисов за одним адресом, канареечные релизы, развод по версиям | Нужен полный разбор запроса: выше задержка на точке входа, сбой одного сервера заметнее |
| Внешний управляемый сервис | Нет своей отказоустойчивой точки входа, нужны готовые сертификаты | Меньше контроля над алгоритмами и таймаутами, привязка к провайдеру |
После выбора режима остаётся распределение запросов и проверки работоспособности: для долгих соединений выгоднее счётчик активных сессий, для сервисов с привязкой к сессии — удержание клиента на узле, а активные пробы выводят сервер из ротации и возвращают его только после нескольких успешных откликов. Так уходит основная причина «плавающих» пятисоток под нагрузкой.
Порядок внедрения: от аудита схемы до передачи в эксплуатацию
Работы идут последовательно: пока не выяснена текущая топология и профиль трафика, любая правка конфигурации — это угадывание. Поэтому начинаем с аудита схемы, а боевой поток переводим на новую конфигурацию только после того, как она отработала на тестовом контуре. Ниже — этапы внедрения.
- Аудит схемы. Собираем фактическую картину: где стоит обратный прокси, какие frontend и backend объявлены, как разложены правила маршрутизации, чем проверяется доступность серверов. Сверяем это с логами ошибок и статистикой по кодам ответов.
- Проектирование целевой схемы. Решаем, что балансируем — HTTP или TCP, где терминируется TLS, как удерживаются сессии пользователя и по каким признакам узел считается нерабочим и выводится из ротации.
- Настройка конфигурации. Описываем frontend и backend, правила маршрутизации, таймауты, лимиты соединений и повторы запросов. Конфигурацию держим в системе контроля версий — каждое изменение проходит ревью.
- Проверка на тестовом контуре. Прогоняем отказы: падение узла, плавный перезапуск, рост нагрузки, истечение сертификата. Критерий готовности — отказ одной ноды незаметен для пользователя.
- Управляемый перенос трафика. Переключаем долями: сначала часть запросов, затем весь поток. Откат на прежнюю схему остаётся доступен одной командой до конца переноса.
- Передача в эксплуатацию. Отдаём дежурной смене карту сервисов, регламент правок, набор метрик и алертов, порядок планового обновления сертификатов и действий при деградации.
Что остаётся у команды: конфигурации, схемы и регламенты
Всё, что мы настраиваем в HAProxy, остаётся у вас в репозитории с историей правок, а не в переписке с инженером. Ниже — перечень артефактов, которые заказчик получает на руки при сдаче: по ним эксплуатация и развитие сервиса не зависят от того, кто именно настраивал конфигурацию.
- Рабочие конфигурации — файлы с комментариями по каждой секции: правила маршрутизации по домену и пути, таймауты, лимиты одновременных соединений, режим балансировки и параметры проверок доступности серверов.
- Схема связей — карта потока запросов: точки терминации шифрования, пулы серверов за прокси, порядок отказоустойчивости, поведение при выпадении узла и логика возврата трафика после восстановления.
- Политики доступа — правила ограничения по адресам и частоте запросов, разделение служебных и публичных маршрутов, работа с заголовками клиента и режим обслуживания во время релиза.
- Регламент отката — пошаговый порядок возврата на предыдущую версию конфигурации: где лежат резервные копии, как проверить конфигурацию перед применением, за какое время выполняется откат.
- Порядок обновления сертификатов — кто отвечает за выпуск, как проходит автоматическое продление, что делать при ошибке проверки и как убедиться, что новый сертификат подхватился без разрыва соединений.
- Инструкции для дежурной смены — типовые сбои и признаки их появления в логах, что можно исправить на месте, а в каких случаях эскалировать задачу, с указанием порогов срабатывания мониторинга.
- Проверка изменений — описание стенда, на котором правки обкатываются до продакшена, и набора проверок, которые должны пройти до применения конфигурации на боевых узлах.
Кейс: как точка входа пережила пиковую нагрузку без деградации
Клиент — сервис личных кабинетов с суточной аудиторией в десятки тысяч человек. Точка входа была одна: весь трафик принимал единственный узел, он же держал сертификаты и завершал защищённые соединения. Пока нагрузка росла плавно, схема справлялась, но на промо-пике упёрлась в предел.
Что было на пике
В часы распродажи одновременных подключений стало вдвое больше обычного, и узел начал упираться в лимит соединений. Доля запросов, завершавшихся ошибкой, доходила до 7%, а время отклика у части пользователей переваливало за 4 секунды — корзины не доживали до оплаты. Отдельная боль: любой перезапуск означал до 9 минут полной недоступности, потому что переключиться было не на кого.
Что изменили
Собрали отказоустойчивую пару узлов HAProxy в двух разных зонах доступности, объединив их общим виртуальным адресом. Активный узел принимает трафик, резервный постоянно проверяет его состояние и перехватывает адрес при отказе — за доли секунды, без разрыва уже установленных соединений. Отдельно пересчитали очереди и таймауты под реальный профиль запросов, чтобы медленный клиент не занимал слоты здоровых.
Что стало
Простой при отказе узла сократился с 9 минут до менее секунды — пользователь не успевает заметить переключение. Доля ошибок на пике упала с 7% до 0,2%, а время отклика на том же объёме трафика — с 4,5 до 0,8 секунды. Обновления и обслуживание теперь идут по одному узлу: второй держит трафик, отдельное окно недоступности больше не нужно.
Балансировка соединений или маршрутизация по содержимому?
Если трафик неразбираемый — соединение к базе, брокеру очередей, шифрованный поток, который прокси не расшифровывает, — достаточно балансировки соединений: решение принимается один раз при установке связи, и дальше все пакеты идут к одному узлу. Как только появляются HTTP-запросы с разными путями, хостами и заголовками, распределения мало — нужна маршрутизация по содержимому.
Балансировка соединений дешевле: прокси не разбирает запрос, а считает соединения по узлам — по кругу, по числу активных, по адресу клиента, когда сессию надо удержать на одном сервере. Ограничение одно: внутри соединения не видно, где /api, а где статика, поэтому развести нагрузку по типам запросов не получится.
Маршрутизация по содержимому работает на уровне HTTP: запрос разбирается целиком, правила раскладывают его по пулам по хосту, пути или заголовку. Появляются проверки здоровья по коду ответа, а не по открытому порту, метка сессии в cookie и проброс исходного адреса клиента. Цена — вычисления на каждый запрос и общий с приложением набор заголовков.
Совмещение подходов — рабочая схема: узел принимает HTTP-трафик и распределяет его по пулам, а часть пулов оставляет соединения неразобранными — для баз, очередей или шифрованного потока, ключи от которого остаются у владельца сервиса. Выбор режима задаёт и то, какие проверки здоровья будут у пулов, и как вы будете диагностировать сбой.
| Вариант | Когда подходит | Ограничения |
|---|---|---|
| Балансировка соединений | Неразбираемый трафик: базы, очереди, шифрование без расшифровки на прокси | Пути и заголовки не видны, типы запросов не разделить |
| Маршрутизация по содержимому | HTTP-сервисы, несколько приложений, статика отдельно от API | Дороже по вычислениям, нужны согласованные заголовки и правила |
| Совмещение | Смешанный контур: HTTP-маршруты наружу, неразобранные потоки внутри | Схема сложнее, нужна карта пулов и проверок |
Частые технические сомнения перед изменением схемы
При переносе схемы главный вопрос не «заработает ли», а что произойдёт с уже открытыми соединениями в момент переключения. Ниже — четыре сомнения, которые чаще всего всплывают до того, как мы что-то трогаем в рабочем контуре.
Текущие соединения обрываются при переключении узлов?
Для коротких запросов переход незаметен: клиент повторяет обращение, а обратный прокси отправляет его на живой узел. Длинные соединения — потоковые, веб-сокеты — выводятся через мягкое завершение: сервер снимается с ротации, но дожидается ответа по уже открытым сессиям, новые запросы уходят на оставшиеся.
Нужно ли что-то менять в приложении?
В большинстве случаев нет — приложение получает запросы как раньше, меняется только точка входа. Правки нужны там, где код сам вычисляет адрес клиента по заголовкам: если исходный адрес не пробрасывается, в логах и ограничениях по IP появляется адрес балансировщика. Это закрывается настройкой, без выпуска новой версии кода.
Как быстро отключается сбойный узел?
Периодичность и порог проверок задаются явно. При выверенных значениях неработающий узел выпадает из ротации за несколько секунд — столько же занимает возврат после восстановления. Слишком частые проверки дают ложные срабатывания на пике нагрузки, слишком редкие растягивают деградацию, поэтому пороги подбираются по фактическому профилю трафика, а не «на глаз».
Как обновлять конфигурацию без простоя?
Сначала синтаксическая проверка файла, затем плавная перезагрузка: новый процесс поднимается и принимает трафик, старый дорабатывает активные сессии. Окно недоступности нулевое, сокеты не пересоздаются. Откат — возврат предыдущей конфигурации и повтор той же процедуры, поэтому изменения вносим небольшими шагами.
Обсудим задачу и вернёмся с планом внедрения
Чтобы вернуться с планом внедрения, а не с общими договорённостями, нам нужен от вас набор вводных. По ним мы делаем оценку сроков, выбираем алгоритм балансировки и порядок переключения — так работы идут без остановки сервиса.
- Перечень сервисов, которые пойдут через обратный прокси: адреса, порты, протоколы и где терминируются сертификаты — на балансировщике или на стороне приложений.
- Текущая схема: что стоит сейчас (HAProxy или другой балансировщик), как распределяется трафик, какие проверки доступности узлов настроены и как выполняется откат.
- Ожидаемая нагрузка: пиковые запросы в секунду, число одновременных соединений, доля длинных сессий — от этого зависит алгоритм балансировки и лимиты.
- Ограничения по окнам работ: допустимая длительность переключения, есть ли резервный контур, можно ли менять записи в DNS и в какое время.
- Доступы: серверы, репозиторий конфигураций, панель управления сертификатами, права на изменение правил сети.
- Требования к сертификатам: кто выпускает, нужна ли автоматическая замена и проверка цепочки при обновлении.
- Критерии приёмки: отказ узла, всплеск трафика, плановая замена сертификата — и кто со стороны заказчика подтверждает результат.
Этого достаточно, чтобы подготовить план внедрения с этапами, точками отката и оценкой сроков. Опишите задачу — вернёмся с планом и составом работ.







