Перейти до вмісту
Глоссарий 7 хв читання 37 переглядів

Keep-Alive

Дізнайтеся, як Keep-Alive забезпечує постійні з'єднання через проксі-сервери. Ознайомтеся з його перевагами для швидшого перегляду веб-сторінок та зменшення навантаження на сервер.

HTTP
Keep-Alive

Keep-Alive, у контексті постійних з'єднань через проксі, є HTTP-механізмом, який дозволяє одному TCP-з'єднанню залишатися відкритим і повторно використовуватися для кількох HTTP-запитів і відповідей між клієнтом і проксі, а також між проксі та вихідним сервером, тим самим зменшуючи накладні витрати на встановлення нових з'єднань для кожної транзакції.

Розуміння Keep-Alive

HTTP Keep-Alive, також відоме як постійні з'єднання, є фундаментальною оптимізацією для продуктивності веб-додатків. Без Keep-Alive кожен HTTP-запит вимагав би встановлення нового TCP-з'єднання (TCP-рукостискання), за яким слідувала б передача даних, а потім розрив з'єднання. Цей процес тягне за собою значні накладні витрати, особливо для безпечних з'єднань, які також вимагають TLS-рукостискання.

Переваги постійних з'єднань

  • Зменшена затримка: Усуває затримку, пов'язану з TCP- та TLS-рукостисканням для наступних запитів через те саме з'єднання. Це особливо помітно для клієнтів з високим часом кругового обходу (RTT).
  • Зменшене використання CPU та пам'яті: Менш часте встановлення та розрив з'єднань зменшує обчислювальне навантаження на клієнтів, проксі та вихідні сервери. Це включає цикли CPU для операцій із сокетами, пам'ять для стану з'єднання та використання файлових дескрипторів.
  • Зменшення перевантаження мережі: Менша кількість відкритих і закритих TCP-з'єднань означає менше сигнального трафіку (пакетів SYN, SYN-ACK, FIN, FIN-ACK) у мережі.
  • Покращена пропускна здатність: Дозволяє ефективніше використовувати механізми контролю перевантаження TCP, оскільки з'єднання з часом можуть досягати вищих швидкостей пропускної здатності.

Keep-Alive в HTTP/1.x

Реалізація та поведінка Keep-Alive за замовчуванням відрізняються між HTTP/1.0 та HTTP/1.1.

HTTP/1.0 Keep-Alive

В HTTP/1.0 постійні з'єднання не були типовими. Клієнти повинні були явно запитувати Keep-Alive, включаючи заголовок Connection: keep-alive у своїх запитах. Сервери відповідали тим самим заголовком, щоб вказати на свою підтримку постійних з'єднань. Якщо жодна зі сторін не включала цей заголовок, з'єднання закривалося після поточної відповіді.

HTTP/1.1 Keep-Alive

HTTP/1.1 зробив постійні з'єднання поведінкою за замовчуванням. Якщо явно не вказано інше, клієнти та сервери припускають, що з'єднання повинно залишатися відкритим після транзакції. Щоб закрити з'єднання, будь-яка сторона повинна надіслати заголовок Connection: close. Ця зміна значно покращила продуктивність веб-додатків за замовчуванням.

Заголовок Connection як Hop-by-Hop заголовок

Заголовок Connection є hop-by-hop заголовком. Це означає, що він призначений лише для прямого з'єднання між двома сторонами, що спілкуються (наприклад, клієнт-проксі або проксі-вихідний сервер), і не повинен ретранслюватися проксі або посередниками. Проксі повинні видаляти або змінювати hop-by-hop заголовки перед пересиланням запитів або відповідей. Невиконання цього може призвести до порушень протоколу та несподіваної поведінки, оскільки нижній сервер або клієнт можуть неправильно інтерпретувати інструкції з керування з'єднанням.

Інші поширені hop-by-hop заголовки включають Keep-Alive, Proxy-Authenticate, Proxy-Authorization, TE, Trailers та Upgrade.

Keep-Alive через проксі

Проксі відіграють критичну роль в управлінні постійними з'єднаннями. Вони зазвичай підтримують два набори постійних з'єднань:

  1. З'єднання клієнт-проксі: Проксі підтримує постійні з'єднання зі своїми клієнтами.
  2. З'єднання проксі-вихідний сервер: Проксі підтримує постійні з'єднання з вихідними серверами, на які він пересилає запити.

Роль проксі в управлінні заголовками

Коли проксі отримує заголовок Connection: keep-alive від клієнта, він розуміє, що клієнт хоче залишити з'єднання з проксі відкритим. Однак проксі не повинен пересилати цей заголовок Connection на вихідний сервер. Натомість проксі самостійно вирішує, чи встановлювати постійне з'єднання з вихідним сервером на основі власної конфігурації та можливостей вихідного сервера.

Поширеним шаблоном для проксі, особливо при роботі з HTTP/1.1, є видалення заголовка Connection з вхідних запитів клієнта та подальше окреме керування вихідним з'єднанням до вихідного сервера. Якщо проксі хоче використовувати постійні з'єднання HTTP/1.1 вгору за течією, він просто опускає заголовок Connection: close.

# Приклад конфігурації Nginx для проксіювання HTTP/1.1 з Keep-Alive
location / {
    proxy_pass http://backend_server;
    proxy_http_version 1.1; # Вказує Nginx використовувати HTTP/1.1 для вихідного з'єднання
    proxy_set_header Connection ""; # Видаляє заголовок Connection із запитів клієнта,
                                    # щоб Nginx самостійно керував Keep-Alive для вихідного з'єднання.
                                    # Це критично для правильної обробки hop-by-hop заголовків.
}

У цьому прикладі Nginx, proxy_http_version 1.1; гарантує, що Nginx використовує HTTP/1.1 при підключенні до backend_server. За замовчуванням з'єднання HTTP/1.1 є постійними. proxy_set_header Connection ""; явно видаляє заголовок Connection, який міг надійти від клієнта, запобігаючи його пересиланню на вихідний сервер і дозволяючи Nginx правильно керувати власними постійними з'єднаннями вгору за течією.

Пул з'єднань

Проксі часто реалізують пул з'єднань для своїх вихідних з'єднань до вихідних серверів. Це означає, що вони підтримують пул неактивних, відкритих TCP-з'єднань до різних вихідних серверів. Коли надходить новий запит для певного джерела, проксі спочатку перевіряє, чи доступне неактивне з'єднання до цього джерела в пулі. Якщо так, він повторно використовує це з'єднання. Якщо ні, встановлюється нове з'єднання. Це ще більше підвищує ефективність, зменшуючи кількість нових з'єднань, які проксі потрібно встановити.

Тайм-аути Keep-Alive та управління ресурсами

Хоча постійні з'єднання є корисними, вони вимагають ретельного управління, щоб запобігти вичерпанню ресурсів на проксі та вихідних серверах.

Механізми тайм-ауту

Кожна сторона (клієнт, проксі, вихідний сервер) може вказати тайм-аут keep-alive. Якщо протягом цього періоду тайм-ауту на постійному з'єднанні не обмінюються дані, з'єднання закривається.

  • Тайм-аут на стороні клієнта: Клієнт може закрити своє з'єднання з проксі, якщо він не надсилає інший запит протягом певного періоду.
  • Тайм-аут на стороні проксі: Проксі може налаштувати власні тайм-аути keep-alive як для з'єднань, що звернені до клієнта, так і для з'єднань, що звернені до джерела. Якщо неактивне з'єднання клієнт-проксі або проксі-вихідний сервер перевищує свій тайм-аут, проксі закриє його.
  • Тайм-аут вихідного сервера: Вихідний сервер закриє своє з'єднання з проксі, якщо воно залишається неактивним занадто довго.

Невідповідність тайм-аутів може призвести до проблем. Наприклад, якщо вихідний сервер має коротший тайм-аут keep-alive, ніж проксі, джерело може закрити з'єднання, яке проксі все ще вважає відкритим. Коли проксі спробує повторно використати це "застаріле" з'єднання, він зіткнеться з помилкою (наприклад, скиданням з'єднання) і йому доведеться повторити запит на новому з'єднанні. Це додає затримки та збільшує кількість помилок. Тому, як правило, рекомендується налаштовувати тайм-аути keep-alive проксі-вихідний сервер трохи коротшими або рівними тайм-аутам вихідного сервера.

Максимальна кількість з'єднань

Проксі також повинні обмежувати загальну кількість постійних з'єднань, які вони підтримують, як до клієнтів, так і до вихідних серверів. Кожне відкрите з'єднання споживає системні ресурси (пам'ять, файлові дескриптори). Необмежені постійні з'єднання можуть призвести до:

  • Вичерпання файлових дескрипторів: Проксі вичерпує доступні файлові дескриптори.
  • Вичерпання пам'яті: Занадто багато відкритих з'єднань споживають надмірну пам'ять.
  • Збільшення навантаження на CPU: Управління великою кількістю неактивних з'єднань все ще тягне за собою певні накладні витрати.

Конфігурації проксі зазвичай дозволяють адміністраторам встановлювати keep-alive_timeout та keep-alive_requests (максимальна кількість запитів, дозволених через одне постійне з'єднання, перш ніж воно буде закрито та створено заново).

# Приклад Nginx: налаштування Keep-Alive для з'єднань, що звернені до клієнта
http {
    keepalive_timeout 60s; # Тайм-аут Keep-Alive клієнт-Nginx
    keepalive_requests 1000; # Максимальна кількість запитів на одне Keep-Alive з'єднання клієнт-Nginx
    # ...
}

# Приклад Nginx: налаштування Keep-Alive для з'єднань проксі-вихідний сервер
location / {
    proxy_pass http://backend_server;
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    # Необов'язково: налаштуйте конкретні параметри Keep-Alive для вихідного з'єднання, якщо потрібно
    # Поведінка Nginx за замовчуванням для Keep-Alive вихідного з'єднання полягає в повторному використанні з'єднань,
    # доки вони явно не будуть закриті вихідним сервером або не закінчиться тайм-аут Nginx.
    # Для більш явного контролю над пулом з'єднань вихідного сервера:
    # proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    # proxy_connect_timeout 5s;
    # proxy_read_timeout 10s;
    # proxy_send_timeout 10s;
}

Keep-Alive в HTTP/2 та далі

HTTP/2 представив мультиплексування, дозволяючи надсилати кілька HTTP-запитів та відповідей одночасно через одне TCP-з'єднання. Це за своєю суттю забезпечує переваги Keep-Alive без необхідності явних заголовків Connection: keep-alive на рівні програми. З'єднання HTTP/2, після встановлення, призначене для того, щоб залишатися відкритим і обробляти весь трафік між клієнтом і сервером (або клієнтом і проксі, проксі та джерелом), доки воно явно не буде закрито або не закінчиться тайм-аут.

Хоча HTTP/2 абстрагує явний заголовок Keep-Alive, основний принцип підтримки постійного TCP-з'єднання для зменшення накладних витрат залишається вирішальним. Проксі, які підтримують HTTP/2, керуватимуть постійним з'єднанням HTTP/2 з клієнтом і можуть перетворювати запити на постійні з'єднання HTTP/1.1 або з'єднання HTTP/2 з вихідним сервером, залежно від можливостей вихідного сервера та конфігурації проксі. Роль проксі в управлінні цими базовими TCP-з'єднаннями та їх тайм-аутами все ще є життєво важливою для продуктивності та управління ресурсами.

Підсумок поведінки Keep-Alive

Функція HTTP/1.0 HTTP/1.1 HTTP/2
Постійність за замовчуванням Ні, з'єднання закриваються після кожного запиту. Так, з'єднання постійні за замовчуванням. Так, одне TCP-з'єднання для кількох потоків.
Заголовок для постійності Connection: keep-alive (явний) Connection: close для завершення (явний) Н/Д (мультиплексування обробляє постійність)
Пайплайнінг запитів Можливий, але складний (блокування початку черги) Можливий, але складний (блокування початку черги) Так, повне мультиплексування
Управління проксі Проксі повинен керувати заголовком Connection і вирішувати питання постійності вихідного з'єднання. Проксі повинен видаляти заголовок Connection і керувати постійністю вихідного з'єднання. Проксі керує потоком HTTP/2 через постійний TCP.
Зменшення накладних витрат Зменшує накладні витрати на TCP-рукостискання. Значно зменшує накладні витрати на TCP-рукостискання. Повністю усуває накладні витрати на TCP/TLS-рукостискання для кожного запиту.
Оновлено: 03.03.2026
Назад до категорії

Спробуйте наші проксі

20,000+ проксі в 100+ країнах світу

support_agent
GProxy Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.