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 і в який час.
- Доступи: сервери, репозиторій конфігурацій, панель керування сертифікатами, права на зміну правил мережі.
- Вимоги до сертифікатів: хто випускає, чи потрібна автоматична заміна й перевірка ланцюжка під час оновлення.
- Критерії приймання: відмова вузла, сплеск трафіку, планова заміна сертифіката — і хто з боку замовника підтверджує результат.
Цього достатньо, щоб підготувати план впровадження з етапами, точками відкату й оцінкою строків. Опишіть задачу — повернемося з планом і складом робіт.







