Чи дозволяють зворотні проксі-сервери HTTP зазвичай підтримувати HTTP Keep-Alive на клієнтській стороні проксі-з'єднання, а не на стороні сервера?


30

HAProxy має можливість увімкнути HTTP в режимі "живого" на стороні клієнта (клієнт <-> HAProxy), але відключити його на стороні сервера (HAProxy <-> сервер).

Деякі наші клієнти підключаються до нашої веб-служби за допомогою супутника, тому затримка становить ~ 600 мс, і я думаю, що, включивши в режим збереження життя, це трохи прискорить роботу. Чи правий я?

Чи підтримує це Nginx? Це широко реалізована функція в інших програмних та апаратних балансирах навантаження? Що ще, крім HAProxy?

Відповіді:


43

редагувати: Моя відповідь стосується лише оригінального нередагованого запитання, яке стосується того, чи характерний такий варіант для балансирів навантажень / зворотних проксі. Я не впевнений, чи підтримує nginx / product X це 99,9% мого досвіду зворотного доступу до HAproxy.

Правильно. HTTP Keep-Alive на стороні клієнта, але не на стороні сервера.

Чому?

Якщо ви розділите кілька деталей, ви можете швидко зрозуміти, чому це користь. У цьому прикладі зробимо вигляд, що завантажуємо сторінку www.example.com, і ця сторінка містить 3 зображення, img [1-3] .jpg.

Веб-переглядач завантажує сторінку, без Keep-Alive

  1. Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
  2. Клієнт робить HTTP GET запит на "/"
  3. Сервер надсилає вміст HTML URI "/" (який включає теги HTML, що посилаються на 3 зображення)
  4. Сервер закриває TCP-з'єднання
  5. Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
  6. Клієнт робить HTTP GET запит на "/img1.jpg"
  7. Сервер надсилає зображення
  8. Сервер закриває TCP-з'єднання
  9. Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
  10. Клієнт робить HTTP GET запит на "/img2.jpg"
  11. Сервер надсилає зображення
  12. Сервер закриває TCP-з'єднання
  13. Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
  14. Клієнт робить HTTP GET запит на "/img3.jpg"
  15. Сервер надсилає зображення
  16. Сервер закриває TCP-з'єднання

Зауважте, що встановлено 4 окремі сеанси TCP та закриті.

Веб-переглядач завантажує сторінку із Keep-Alive

HTTP Keep-Alive дозволяє для одного TCP-з'єднання обслуговувати кілька запитів HTTP, один за одним.

  1. Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
  2. Клієнт робить HTTP GET запит на "/", а також просить сервер зробити це HTTP-сеансом збереження-збереження.
  3. Сервер надсилає вміст HTML URI "/" (який включає теги HTML, що посилаються на 3 зображення)
  4. Сервер не закриває з'єднання TCP
  5. Клієнт робить і HTTP GET запит на "/img1.jpg"
  6. Сервер надсилає зображення
  7. Клієнт робить і HTTP GET запит на "/img2.jpg"
  8. Сервер надсилає зображення
  9. Клієнт робить і HTTP GET запит на "/img3.jpg"
  10. Сервер надсилає зображення
  11. Сервер закриває TCP-з'єднання, якщо більше HTTP-запитів не надходило протягом його періоду очікування зберігання-зберігання

Зауважте, що в режимі Keep-Alive встановлено лише 1 TCP-з'єднання і врешті-решт закрите.

Чому Keep-Alive краще?

Щоб відповісти на це, ви повинні зрозуміти, що потрібно для встановлення TCP-зв’язку між клієнтом і сервером. Це називається тристороннім рукостисканням TCP.

  1. Клієнт відправляє пакет SYN (chronise)
  2. Сервер повертає SYN (хронізований) ACK (теперішній випуск), SYN-ACK
  3. Клієнт надсилає пакет ACK (в даний час)
  4. TCP-з'єднання зараз вважається активним і клієнтом, і сервером

Мережі мають затримку, тому кожен крок тривимірного рукостискання займає певну кількість часу. Скажімо, що між клієнтом і сервером існує 30 мс, передача IP-пакетів, необхідних для встановлення з'єднання TCP, означає, що для встановлення TCP-з'єднання потрібно 3 х 30 мс = 90 мс.

Це може здатися не дуже схожим, але якщо врахувати, що в нашому оригінальному прикладі ми повинні встановити 4 окремих TCP-з'єднання, це стає 360 мс. Що робити, якщо затримка між клієнтом і сервером становить 100 мс замість 30 мс? Тоді наші 4 з'єднання займають 1200 мс для встановлення.

Ще гірше, що для типової веб-сторінки для завантаження може знадобитися набагато більше, ніж лише 3 зображення, може бути кілька CSS, JavaScript, зображень або інших файлів, які потрібно запитувати клієнту. Якщо на сторінці завантажено 30 інших файлів, а затримка клієнт-сервер становить 100 мс, як довго ми витрачаємо на встановлення TCP-з'єднань?

  1. Для встановлення 1 TCP-з'єднання потрібно 3 х затримки, тобто 3 х 100 мс = 300 мс.
  2. Ми повинні зробити це 31 раз, один раз для сторінки, і ще 30 разів для кожного іншого файлу, на який посилається сторінка. 31 х 300 мс = 9,3 секунди.

На завантаження веб-сторінки, на яку посилаються 30 інших файлів, витрачено 9,3 секунди. І це навіть не рахує часу, витраченого на надсилання HTTP-запитів та отримання відповідей.

З HTTP Keep-Alive нам потрібно встановити лише 1 TCP-з'єднання, яке займає 300 мс.

Якщо HTTP Keep-Alive настільки великий, чому б не використовувати його і на стороні сервера?

Зворотні проксі-сервери HTTP (як-от HAproxy) зазвичай розгортаються впритул до резервних серверів, до яких вони наближаються. У більшості випадків затримка між зворотним проксі-сервером та його серверним сервером / сервісами буде менше 1 мс, тому встановлення TCP-з'єднання відбувається набагато швидше, ніж між клієнтом.

Це лише половина причини. Сервер HTTP виділяє певний об'єм пам'яті для кожного клієнтського з'єднання. З Keep-Alive він підтримуватиме з'єднання живим, а за допомогою розширення він зберігатиме певний об'єм пам'яті, що використовується на сервері, до тих пір, поки не буде досягнуто часу очікування Keep-Alive, яке може становити до 15 секунд, залежно від конфігурації сервера .

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

Відмова від відповідальності: так, це пояснення не враховує той факт, що браузери зазвичай встановлюють кілька HTTP-з'єднань із сервером паралельно. Однак існує обмеження кількості паралельних з'єднань, які браузер зробить з тим самим хостом, і, як правило, це все ще досить мало, щоб зробити живим бажане.


5
Кудо, за чудове пояснення Грейм, я ніколи не витрачав достатньо часу на таку довгу відповідь тому, хто мене про це запитав, і я обов'язково триматиму посилання на цю посаду, щоб вона слугувала дуже чіткою відповіддю зараз :-)
Віллі Тарро

2
Чи була б перевага для KeepAlive на стороні сервера, якби зв’язок між проксі та бекендом був https?
Авмохан

"HTTP-сервер виділяє певний об'єм пам'яті для кожного клієнтського з'єднання" так, але таких з'єднань буде мало (?) Лише один на балансир завантаження? Не один на клієнта в Інтернеті (?)
Raedwald

@Raedwald, якщо ваш балансир навантаження обмежений встановленням одного HTTP-з'єднання до кожного резервного сервера, у вас буде дуже поганий час. :-)
ThatGraemeGuy

7

Nginx підтримує живі з обох сторін.


Ви б сказали, що зберігати в живих корисно для бек-ендів, якби між проксі-сервером та резервними програмами затримка існувала? Крім того, яка оптимальна кількість збережених живих з'єднань дозволена?
CMCDragonkai

@CMCDragonkai Якщо ваші програмні пакети розміщені на спеціалізованих серверах, це може бути корисно, щоб уникнути затримки підключення, яка залежить від вашої мережі. Золотої середини немає, оптимальне число головним чином залежить від вашого налаштування, оточення, вашої заявки та схеми запиту.
VBart

Я сподіваюсь знайти рівняння, яке вирішить це!
CMCDragonkai

2
Як я читав, питання не в тому, чи підтримує nginx підтримку "живого" у висхідному потоці, але чи підтримує nginx відключення функції "live-live" на верхній стороні.
користувач45793
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.