редагувати: Моя відповідь стосується лише оригінального нередагованого запитання, яке стосується того, чи характерний такий варіант для балансирів навантажень / зворотних проксі. Я не впевнений, чи підтримує nginx / product X це 99,9% мого досвіду зворотного доступу до HAproxy.
Правильно. HTTP Keep-Alive на стороні клієнта, але не на стороні сервера.
Чому?
Якщо ви розділите кілька деталей, ви можете швидко зрозуміти, чому це користь. У цьому прикладі зробимо вигляд, що завантажуємо сторінку www.example.com, і ця сторінка містить 3 зображення, img [1-3] .jpg.
Веб-переглядач завантажує сторінку, без Keep-Alive
- Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
- Клієнт робить HTTP GET запит на "/"
- Сервер надсилає вміст HTML URI "/" (який включає теги HTML, що посилаються на 3 зображення)
- Сервер закриває TCP-з'єднання
- Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
- Клієнт робить HTTP GET запит на "/img1.jpg"
- Сервер надсилає зображення
- Сервер закриває TCP-з'єднання
- Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
- Клієнт робить HTTP GET запит на "/img2.jpg"
- Сервер надсилає зображення
- Сервер закриває TCP-з'єднання
- Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
- Клієнт робить HTTP GET запит на "/img3.jpg"
- Сервер надсилає зображення
- Сервер закриває TCP-з'єднання
Зауважте, що встановлено 4 окремі сеанси TCP та закриті.
Веб-переглядач завантажує сторінку із Keep-Alive
HTTP Keep-Alive дозволяє для одного TCP-з'єднання обслуговувати кілька запитів HTTP, один за одним.
- Клієнт встановлює TCP-з'єднання з www.example.com на порту 80
- Клієнт робить HTTP GET запит на "/", а також просить сервер зробити це HTTP-сеансом збереження-збереження.
- Сервер надсилає вміст HTML URI "/" (який включає теги HTML, що посилаються на 3 зображення)
- Сервер не закриває з'єднання TCP
- Клієнт робить і HTTP GET запит на "/img1.jpg"
- Сервер надсилає зображення
- Клієнт робить і HTTP GET запит на "/img2.jpg"
- Сервер надсилає зображення
- Клієнт робить і HTTP GET запит на "/img3.jpg"
- Сервер надсилає зображення
- Сервер закриває TCP-з'єднання, якщо більше HTTP-запитів не надходило протягом його періоду очікування зберігання-зберігання
Зауважте, що в режимі Keep-Alive встановлено лише 1 TCP-з'єднання і врешті-решт закрите.
Чому Keep-Alive краще?
Щоб відповісти на це, ви повинні зрозуміти, що потрібно для встановлення TCP-зв’язку між клієнтом і сервером. Це називається тристороннім рукостисканням TCP.
- Клієнт відправляє пакет SYN (chronise)
- Сервер повертає SYN (хронізований) ACK (теперішній випуск), SYN-ACK
- Клієнт надсилає пакет ACK (в даний час)
- TCP-з'єднання зараз вважається активним і клієнтом, і сервером
Мережі мають затримку, тому кожен крок тривимірного рукостискання займає певну кількість часу. Скажімо, що між клієнтом і сервером існує 30 мс, передача IP-пакетів, необхідних для встановлення з'єднання TCP, означає, що для встановлення TCP-з'єднання потрібно 3 х 30 мс = 90 мс.
Це може здатися не дуже схожим, але якщо врахувати, що в нашому оригінальному прикладі ми повинні встановити 4 окремих TCP-з'єднання, це стає 360 мс. Що робити, якщо затримка між клієнтом і сервером становить 100 мс замість 30 мс? Тоді наші 4 з'єднання займають 1200 мс для встановлення.
Ще гірше, що для типової веб-сторінки для завантаження може знадобитися набагато більше, ніж лише 3 зображення, може бути кілька CSS, JavaScript, зображень або інших файлів, які потрібно запитувати клієнту. Якщо на сторінці завантажено 30 інших файлів, а затримка клієнт-сервер становить 100 мс, як довго ми витрачаємо на встановлення TCP-з'єднань?
- Для встановлення 1 TCP-з'єднання потрібно 3 х затримки, тобто 3 х 100 мс = 300 мс.
- Ми повинні зробити це 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-з'єднань із сервером паралельно. Однак існує обмеження кількості паралельних з'єднань, які браузер зробить з тим самим хостом, і, як правило, це все ще досить мало, щоб зробити живим бажане.