Проксі-сервіси підтримують HTTP/2, виступаючи як посередник, який може або завершувати з'єднання HTTP/2 та пересилати запити через HTTP/1.1 до вихідних серверів, або пропускати HTTP/2 наскрізно між клієнтом та вихідним сервером.
HTTP/2 є значною переробкою протоколу HTTP, розробленою для покращення продуктивності вебу шляхом усунення властивих обмежень HTTP/1.1. Ключові функції включають повне мультиплексування запитів та відповідей, стиснення заголовків за допомогою HPACK, серверний push та пріоритизацію запитів. Для проксі-сервісу управління цими функціями вимагає специфічних архітектурних рішень для використання переваг HTTP/2, зберігаючи при цьому сумісність та контроль.
Основи протоколу HTTP/2
HTTP/2 працює через одне з'єднання TCP, встановлюючи кілька двонаправлених потоків для одночасного обміну повідомленнями запитів та відповідей. Це мультиплексування усуває блокування початку черги, присутнє в HTTP/1.1. Стиснення заголовків (HPACK) зменшує накладні витрати, кодуючи заголовки HTTP у компактний бінарний формат та підтримуючи спільну динамічну таблицю. Серверний push дозволяє серверу проактивно надсилати клієнту ресурси, які, як він очікує, будуть потрібні, зменшуючи затримку.
Ці функції, хоча й корисні, створюють складнощі для проксі-сервісів, які традиційно працюють за моделлю "запит-відповідь" через окремі з'єднання TCP.
Архітектури проксі для HTTP/2
Проксі-сервіси зазвичай реалізують одну з двох основних архітектур для підтримки HTTP/2: термінацію або наскрізне (end-to-end) проксіювання.
Термінація HTTP/2 (Frontend HTTP/2, Backend HTTP/1.1)
У цій моделі проксі-сервер встановлює з'єднання HTTP/2 з клієнтом. Він завершує протокол HTTP/2, декодує запити, а потім пересилає їх до вихідного сервера, використовуючи HTTP/1.1. Відповіді від вихідного сервера (HTTP/1.1) потім перекодовуються назад в HTTP/2 і надсилаються клієнту.
Потік процесу:
- Клієнт ініціює з'єднання HTTP/2 до проксі (зазвичай через TLS з ALPN, що узгоджує
h2). - Проксі отримує фрейми HTTP/2, реконструює запити, подібні до HTTP/1.1 (включаючи декодування заголовків HPACK).
- Проксі пересилає запити HTTP/1.1 до вихідного сервера.
- Вихідний сервер відповідає за допомогою HTTP/1.1.
- Проксі отримує відповіді HTTP/1.1, кодує їх у фрейми HTTP/2 (включаючи стиснення HPACK) і надсилає їх клієнту.
Переваги:
- Сумісність з бекендом: Вихідні сервери не потребують підтримки HTTP/2. Це корисно для застарілих систем або сервісів, які ще не оновилися.
- Розвантаження: Проксі обробляє обчислювальні накладні витрати на узгодження протоколу HTTP/2, стиснення/розпакування заголовків та управління потоками, зменшуючи навантаження на вихідні сервери.
- Контроль: Легше виконувати традиційні функції проксі, такі як кешування, балансування навантаження, модифікація запитів та фільтрація безпеки, які часто розроблені для семантики HTTP/1.1.
Недоліки:
- Втрата функцій: Функції HTTP/2, такі як серверний push від вихідного сервера, не можуть бути безпосередньо передані. Проксі потрібно було б реалізувати власну логіку серверного push.
- Накладні витрати на невідповідність протоколів: Постійне перекодування між HTTP/2 та HTTP/1.1 створює накладні витрати на обробку на проксі.
- Збільшена затримка: Додатковий етап обробки може спричинити незначну затримку порівняно з прямим з'єднанням HTTP/2.
Випадок використання: Ідеально підходить для сценаріїв, де бажані переваги продуктивності HTTP/2 на стороні клієнта, але інфраструктура бекенду ще не готова до HTTP/2, або коли потрібні широкі маніпуляції запитами на стороні проксі.
Наскрізне HTTP/2 (Full Proxy)
У наскрізній (end-to-end) конфігурації проксі HTTP/2 проксі підтримує з'єднання HTTP/2 як з клієнтом, так і з вихідним сервером. Проксі діє як прозорий посередник, пересилаючи фрейми або потоки HTTP/2 безпосередньо без перетворення протоколу.
Потік процесу:
- Клієнт ініціює з'єднання HTTP/2 до проксі.
- Проксі встановлює з'єднання HTTP/2 до вихідного сервера.
- Проксі пересилає фрейми/потоки HTTP/2 між клієнтом та вихідним сервером.
- Проксі керує ідентифікаторами потоків і потенційно пріоритизує потоки.
Переваги:
- Повне збереження функцій: Усі функції HTTP/2, включаючи серверний push від вихідного сервера, пріоритизацію потоків та стиснення HPACK, зберігаються наскрізно.
- Нижча затримка: Усуває накладні витрати на перекодування, потенційно призводячи до нижчої затримки, якщо вихідний сервер географічно близький або високо оптимізований для HTTP/2.
- Зменшені накладні витрати проксі: Роль проксі полягає переважно в пересиланні фреймів та управлінні потоками, а не в повному перетворенні протоколу.
Недоліки:
- Вимога до вихідного сервера: Вимагає, щоб вихідний сервер повністю підтримував HTTP/2.
- Зменшена видимість/контроль: Пряма маніпуляція заголовками HTTP або тілами запитів проксі стає складнішою через стиснення HPACK та бінарну природу фреймів HTTP/2. Глибока інспекція пакетів часто вимагає повного декодування та повторного кодування фреймів.
- Наслідки для безпеки: Якщо з'єднання з вихідним сервером також є TLS, проксі діє як точка завершення TLS і повторно встановлює нове з'єднання TLS з вихідним сервером, потенційно впливаючи на стан безпеки або вимагаючи управління сертифікатами.
Випадок використання: Найкраще підходить, коли як клієнти, так і вихідні сервери підтримують HTTP/2, і метою є максимізація переваг продуктивності HTTP/2 по всьому шляху з'єднання, з мінімальним втручанням на стороні проксі, окрім маршрутизації та балансування навантаження.
Ключові міркування для проксі-сервісів
Узгодження протоколу прикладного рівня (ALPN)
HTTP/2 зазвичай узгоджується через TLS за допомогою ALPN. Коли клієнт підключається до проксі, він надсилає розширення ALPN у повідомленні TLS ClientHello, вказуючи підтримку h2 (HTTP/2 через TLS) та http/1.1. Проксі вибирає бажаний протокол.
Приклад (Концептуальне рукостискання ALPN):
ClientHello (ALPN: [h2, http/1.1]) -> Proxy
Proxy selects h2
ServerHello (ALPN: h2) <- Proxy
Перетворення заголовків та HPACK
При переході між HTTP/2 та HTTP/1.1 (модель термінації) проксі повинен розпакувати заголовки HPACK із запитів HTTP/2 та повторно закодувати заголовки HTTP/1.1 у HPACK для відповідей HTTP/2. Це включає управління динамічною таблицею HPACK, яка є становою.
Управління потоками та пріоритизація
HTTP/2 дозволяє кілька одночасних потоків через одне з'єднання. Проксі повинен керувати цими потоками, відображаючи їх на бекенд-з'єднання (для бекендів HTTP/1.1) або пересилаючи їх, дотримуючись підказок пріоритету. Неправильне управління потоками може нівелювати переваги мультиплексування HTTP/2.
Обробка серверного push
- Термінація: Якщо проксі завершує HTTP/2, він не може безпосередньо пересилати запити серверного push від вихідного сервера. Проксі може реалізувати власну логіку серверного push на основі аналізу вмісту або конфігурації.
- Наскрізне (End-to-End): У наскрізній конфігурації фрейми серверного push від вихідного сервера пересилаються безпосередньо клієнту.
Інспекція та модифікація трафіку
Інспекція або модифікація трафіку HTTP/2 є складнішою, ніж HTTP/1.1.
* Шифрування: HTTP/2 майже повсюдно використовується з TLS, що вимагає від проксі завершення TLS для інспекції.
* Стиснення заголовків: Модифікація заголовків вимагає декодування, модифікації та повторного кодування за допомогою HPACK, що може бути становим та складним.
Балансування навантаження
З HTTP/2 кілька запитів від одного клієнта можуть надходити через одне з'єднання. Балансувальники навантаження повинні вирішити, чи маршрутизувати всі потоки від одного клієнтського з'єднання до одного бекенд-сервера (прив'язка сесії) або розподіляти окремі потоки між кількома бекенд-серверами. Останнє вимагає більш складного балансування навантаження з урахуванням потоків.
Приклади конфігурації (Nginx)
Nginx, поширений зворотний проксі, підтримує як термінацію HTTP/2, так і наскрізне проксіювання.
Термінація HTTP/2 (Frontend HTTP/2, Backend HTTP/1.1):
server {
listen 443 ssl http2; # Увімкнути HTTP/2 для клієнтських з'єднань
server_name example.com;
ssl_certificate /etc/nginx/certs/example.com.crt;
ssl_certificate_key /etc/nginx/certs/example.com.key;
location / {
proxy_pass http://backend_servers; # Бекенд - HTTP/1.1
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
# Nginx автоматично перетворює клієнтські запити HTTP/2 на HTTP/1.1 для бекенду
}
}
upstream backend_servers {
server 192.168.1.100:80;
server 192.168.1.101:80;
}
Наскрізне HTTP/2 (Frontend HTTP/2, Backend HTTP/2):
server {
listen 443 ssl http2; # Увімкнути HTTP/2 для клієнтських з'єднань
server_name example.com;
ssl_certificate /etc/nginx/certs/example.com.crt;
ssl_certificate_key /etc/nginx/certs/example.com.key;
location / {
proxy_pass https://backend_h2_servers; # Бекенд - HTTP/2
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_ssl_server_name on; # Передати SNI до бекенду
proxy_http_version 2; # Вказати Nginx використовувати HTTP/2 для з'єднання з бекендом
}
}
upstream backend_h2_servers {
server 192.168.1.100:443;
server 192.168.1.101:443;
}
Порівняння: Термінація HTTP/2 проти Наскрізного проксіювання
| Функція | Термінація HTTP/2 (Frontend H2, Backend H1.1) | Наскрізне HTTP/2 (Frontend H2, Backend H2) |
|---|---|---|
| Підтримка вихідного сервера | Потрібен лише HTTP/1.1 | Потрібен HTTP/2 |
| Перетворення протоколу | Так (H2 <-> H1.1) | Ні (H2 <-> H2) |
| Серверний Push | Лише згенерований проксі | Згенерований вихідним сервером може бути переданий |
| Стиснення заголовків | Проксі обробляє кодування/декодування HPACK | Проксі пересилає стиснуті заголовки |
| Продуктивність | Добра, але з накладними витратами на перекодування | Потенційно краща, менші накладні витрати проксі |
| Контроль проксі | Високий (легка модифікація/інспекція) | Нижчий (складніша модифікація/інспекція) |
| Складність | Помірна | Помірна до високої (управління бекендом H2) |
| Затримка | Трохи вища через перекодування | Потенційно нижча |
Практичні наслідки
Впровадження HTTP/2 у проксі-сервісі безпосередньо впливає на досвід користувача та ефективність інфраструктури. Користувачі отримують вигоду від швидшого завантаження сторінок та більш чутливого вебу завдяки мультиплексуванню та стисненню заголовків. Для проксі-інфраструктури підтримка HTTP/2 вимагає ретельного управління ресурсами, особливо щодо використання ЦП для завершення TLS та обробки HPACK. Вибір між термінацією та наскрізним проксіюванням залежить від існуючої архітектури бекенду, цілей продуктивності та потреби в контролі трафіку на рівні проксі. Безпека залишається першочерговою, при цьому TLS є передумовою для більшості розгортань HTTP/2, що вимагає надійного управління сертифікатами та безпечної конфігурації.