http підтримувати життя в сучасну епоху


92

Отже, на думку автора хапроксі, який знає щось про два про http:

Keep-alive був винайдений, щоб зменшити використання центрального процесора на серверах, коли процесори були в 100 разів повільнішими. Але що не сказано, так це те, що постійні з’єднання споживають багато пам’яті, не використовуючи їх ніхто, крім клієнта, який їх відкрив. Сьогодні в 2009 році центральні процесори дуже дешеві, а пам’ять все ще обмежена кількома гігабайтами в силу архітектури чи ціни. Якщо сайт потребує постійного збереження, існує реальна проблема. Високо завантажені веб-сайти часто вимикають підтримку режиму постійної активності, щоб підтримувати максимальну кількість одночасних клієнтів. Справжнім недоліком відсутності підтримки в живих є дещо збільшена затримка отримання предметів. Для компенсації цього браузери подвоюють кількість одночасних з'єднань на сайтах, що не підтримують підтримку.

http://haproxy.1wt.eu/ )

Це відповідає досвіду інших народів? тобто без збереження життя - результат зараз ледве помітний? (напевно, варто зазначити, що з веб-сокетами тощо - зв’язок залишається «відкритим» незалежно від статусу «живого» - для дуже чутливих програм). Чи більший ефект для людей, віддалених від сервера, чи чи багато артефактів для завантаження з одного хоста під час завантаження сторінки? (Я б вважав, що такі речі, як CSS, зображення та JS, все частіше надходять із CDN, що підтримують кеш).

Думки?

(не впевнений, що це річ із сервера за замовчуванням.com, але я не буду перетинати повідомлення, поки хтось не скаже мені перенести його туди).


1
Варто зазначити, що в інших місцях документації щодо гапрокси, який підтримує життя, згадується в інших більш вигідних умовах. Я хотів би почути про досвід людей, особливо щодо масового хостингу.
Майкл Ніл

"Отримати кращий веб-сервер / сервер додатків"? :-) Новіші конструкції (наприклад, Jetty) із продовженням (подібним) обробкою з'єднання по суті пом'якшують проблеми з пам'яттю / потоком. Крім того, "кілька ГБ" звучить як термін сервера 2008/2009 ;-)

3
Для мене це звучить як поворот. Додатковий RTT, який бере участь у встановленні нової розетки, є жорсткою фізичною межею, яка часто є достатньо довгою, щоб бути помітною для людини, і не може бути зменшена в межах відомих законів фізики. І навпаки, оперативна пам'ять дешева, дешевшає, і немає причин для простою сокета використовувати більше декількох кБ.
Will Dean

2
але що цікаво, це не просто теорія - це автор гапроксі. Все, що я чую, - це теорії та припущення.
Майкл Ніл

Відповіді:


141

Гей, оскільки я автор цього цитування, я відповім :-)

На великих сайтах є дві великі проблеми: одночасне з’єднання та затримка. Одночасне з’єднання спричинене повільними клієнтами, яким потрібен вік для завантаження вмісту, та неактивними станами з’єднання. Ці неактивні стани зв’язку спричинені повторним використанням з’єднання для отримання декількох об’єктів, відомих як підтримка живого, що додатково збільшується затримкою. Коли клієнт знаходиться дуже близько до сервера, він може інтенсивно використовувати з’єднання та гарантувати, що він майже ніколи не працює. Однак коли послідовність закінчується, ніхто не піклується про те, щоб швидко закрити канал, і з'єднання залишається відкритим і невикористаним протягом тривалого часу. Саме тому багато людей пропонують використовувати дуже низький час очікування. На деяких серверах, таких як Apache, найнижчий тайм-аут, який ви можете встановити, становить одну секунду, і це часто занадто багато, щоб витримати великі навантаження: якщо перед вами 20000 клієнтів, і вони щосекунди отримують в середньому один об'єкт, ці 20000 з'єднань будуть постійно встановлені. 20000 одночасних з'єднань на сервері загального призначення, наприклад Apache, величезний, вимагатиме від 32 до 64 ГБ оперативної пам'яті залежно від того, які модулі завантажені, і ви, мабуть, не сподіваєтесь піднятися набагато вище, навіть додавши оперативну пам'ять. На практиці для 20000 клієнтів ви навіть можете побачити від 40000 до 60000 одночасних з'єднань на сервері, оскільки браузери намагатимуться встановити 2-3 з'єднання, якщо вони мають багато об'єктів для отримання. і ви, мабуть, не можете сподіватися піднятися набагато вище, навіть додавши оперативну пам'ять. На практиці для 20000 клієнтів ви навіть можете побачити від 40000 до 60000 одночасних з'єднань на сервері, оскільки браузери намагатимуться встановити 2-3 з'єднання, якщо вони мають багато об'єктів для отримання. і ви, мабуть, не можете сподіватися піднятися набагато вище, навіть додавши оперативну пам'ять. На практиці для 20000 клієнтів ви навіть можете побачити від 40000 до 60000 одночасних з'єднань на сервері, оскільки браузери намагатимуться встановити 2-3 з'єднання, якщо у них є багато об'єктів для отримання.

Якщо ви закриєте з'єднання після кожного об'єкта, кількість одночасних з'єднань різко зменшиться. Дійсно, це зменшиться на коефіцієнт, що відповідає середньому часу завантаження об'єкта до часу між об'єктами. Якщо вам потрібно 50 мс для завантаження об’єкта (мініатюрна фотографія, кнопка тощо ...), і ви завантажуєте в середньому 1 об’єкт в секунду, як зазначено вище, тоді у вас буде лише 0,05 з’єднання на клієнта, що становить лише 1000 одночасне з'єднання для 20000 клієнтів.

Зараз час встановлення нових зв’язків буде рахуватися. Далеко віддалені клієнти зазнають неприємної затримки. Раніше браузери використовували велику кількість одночасних з'єднань, коли функцію підтримання життя було вимкнено. Я пам’ятаю цифри 4 на MSIE та 8 на Netscape. Це дійсно поділило б середню затримку на об’єкт на стільки. Тепер, коли підтримка вжитку присутня всюди, ми вже не спостерігаємо таких великих цифр, оскільки це ще більше збільшує навантаження на віддалені сервери, а браузери піклуються про захист інфраструктури Інтернету.

Це означає, що з сучасними браузерами важче отримати послуги, які не підтримують живий, настільки ж чутливими, як і ті, що підтримують живу. Крім того, деякі браузери (наприклад: Opera) використовують евристику, намагаючись використовувати конвеєр. Конвеєризація - це ефективний спосіб використання режиму підтримання активності, оскільки він майже виключає затримку, надсилаючи кілька запитів, не чекаючи відповіді. Я спробував це на сторінці зі 100 маленькими фотографіями, і перший доступ приблизно вдвічі швидший, ніж без збереження життя, але наступний доступ приблизно в 8 разів швидший, оскільки відповіді настільки малі, що враховується лише затримка (лише Відповіді "304").

Я б сказав, що в ідеалі ми повинні мати кілька налаштувань у браузерах, щоб вони підтримували зв’язок між отриманими об’єктами та негайно скидали його, коли сторінка буде завершена. Але ми цього не бачимо, на жаль.

З цієї причини деякі веб-сайти, на яких потрібно встановити сервери загального призначення, такі як Apache, на лицьовій стороні та які повинні підтримувати велику кількість клієнтів, як правило, повинні вимкнути підтримку постійного життя. А щоб змусити браузери збільшити кількість з'єднань, вони використовують кілька доменних імен, щоб завантаження можна було розпаралелювати. Це особливо проблематично на сайтах, які інтенсивно використовують SSL, оскільки налаштування з’єднання ще вище, оскільки існує ще одна поїздка в обидва кінці.

Сьогодні все частіше спостерігається те, що такі сайти воліють встановлювати легкі інтерфейси, такі як haproxy або nginx, які не мають проблем з обробкою десятків-сотень тисяч одночасних з'єднань, вони дозволяють підтримувати живу активність на стороні клієнта та відключають його на Apache сторона. З цього боку, вартість встановлення з'єднання майже нульова з точки зору центрального процесора і зовсім не помітна з точки зору часу. Таким чином, це забезпечує найкраще з обох світів: низька затримка завдяки підтримці живого з дуже низьким часом очікування на стороні клієнта та низькою кількістю з'єднань на стороні сервера. Всі задоволені :-)

Деякі комерційні продукти додатково покращують це шляхом повторного використання з'єднань між фронтальним балансиром навантаження та сервером та мультиплексування всіх клієнтських з'єднань над ними. Коли сервери наближаються до LB, коефіцієнт виграшу не набагато перевищує попереднє рішення, але він часто вимагає адаптації програми, щоб гарантувати відсутність ризику перетину сеансів між користувачами через несподіваний спільний доступ до з'єднання між кількома користувачами . Теоретично цього ніколи не повинно статися. Реальність набагато інша :-)


1
Дякуємо за повну та вичерпну відповідь! Мене збентежили різні коментарі на сторінці про підтримку життя - але все це має сенс.
Michael Neale

Цікаво, що я спостерігав, як Chrome у linux повторно використовував зв’язок, що підтримується, протягом декількох секунд - тобто часу, необхідного для відкриття іншої вкладки - ця інша вкладка мала інше ім’я хосту, але вирішувалась через підстановочний знак DNS на той самий сервер (маса віртуальний хостинг) - і тим самим повторно використати те саме підключення! (це викликало у мене якесь здивування, не те, що добре - очевидно, якщо підтримувати життя лише на стороні клієнта, це нормально).
Майкл Ніл,

Все, що я чув, було "використовувати щось, крім apache, і це не є великою справою". Те, що я екстраполював, було "вимкнути mod_php і пасажира, і тоді навіть апаш може мати шанс на бій".
coolaj86

@ CoolAJ86: суть абсолютно не в тому, щоб бити Apache, і я особисто цим користуюся. Справа в тому, що чим загальніший сервер, тим менше можливостей у вас буде масштабуватися. Деякі модулі вимагають моделі попередньої вилки, тоді ви не можете масштабувати до величезної кількості з'єднань. Але, як пояснили, це не є великою проблемою, оскільки ви можете поєднувати його з іншим безкоштовним компонентом, таким як гапрокси. Чому б у цьому випадку хтось замінював усе? Краще встановіть haproxy, ніж переживайте клопоти про перевстановлення програми за допомогою іншого сервера!
Віллі Таро

22

За роки, коли це було написано (і розміщено тут на stackoverflow), ми тепер маємо такі сервери, як nginx, які зростають у популярності.

Наприклад, nginx може утримувати відкритими 10000 підключень, що підтримують життєдіяльність, за один процес, маючи лише 2,5 МБ (мегабайт) оперативної пам'яті. Насправді легко тримати відкритими декілька тисяч з'єднань з дуже малою оперативною пам'яттю, і єдиними обмеженнями, які ви досягнете, будуть інші обмеження, такі як кількість відкритих дескрипторів файлів або TCP-з'єднання.

Keep-alive була проблемою не через будь-яку проблему із самою специфікацією keep-alive, а через модель масштабування, засновану на процесах Apache, та збереження живих, зламаних на сервер, архітектура якого не була розроблена для його розміщення.

Особливо проблематичним є Apache Prefork + mod_php + keep-alives. Це модель, при якій кожне підключення продовжуватиме займати всю оперативну пам’ять, яку займає PHP-процес, навіть якщо воно повністю не працює і залишається відкритим лише для підтримки. Це не є масштабованим. Але сервери не повинні бути спроектовані таким чином - немає особливих причин, чому серверу потрібно тримати кожне з'єднання, що підтримує активність, в окремому процесі (особливо не тоді, коли кожен такий процес має повний інтерпретатор PHP). PHP-FPM та модель обробки сервера на основі подій, така як у nginx, елегантно вирішують проблему.

Оновлення 2015:

SPDY та HTTP / 2 замінюють функціонал підтримки HTTP на щось ще краще: здатність не тільки підтримувати зв’язок і робити кілька запитів та відповідей по ньому, але й мультиплексувати, тому відповіді можна надсилати в будь-якому порядку і паралельно, а не лише в тому порядку, в якому вони просили. Це запобігає повільним реакціям, блокуючи швидші, і усуває спокусу браузерів тримати відкритими кілька паралельних з'єднань з одним сервером. Ці технології надалі підкреслюють неадекватність підходу mod_php та переваги чогось на кшталт подійного (або, принаймні, багатопотокового) веб-сервера, поєднаного окремо з чимось на зразок PHP-FPM.


2

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


так - це було б моє припущення. можливо, це компроміс - є момент, коли затримка (через відстань) означає, що це справжня проблема
Майкл Ніл

гаразд, отже, сучасна типографіка дозволить вам підключитися до проксі-сервера, який знаходиться поруч (можливо). але тоді ви поширюєте питання на те, щоб довірені особи використовували постійні з'єднання?
catchpolenet

@Michael Neale також, через такі речі, як повільний запуск TCP, фактичний штраф за затримку набагато гірший, ніж можна було б очікувати.
MartinodF

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

2

Дуже довгі режими збереження можуть бути корисними, якщо ви використовуєте CDN "походження", наприклад CloudFront або CloudFlare. Насправді це може виявитись швидшим, ніж відсутність CDN, навіть якщо ви обслуговуєте повністю динамічний вміст.

Якщо ви довго тримаєте живих людей таким чином, що кожен PoP в основному має постійне з'єднання з вашим сервером, тоді, коли користувачі вперше відвідують ваш сайт, вони можуть зробити швидке рукостискання TCP зі своїм локальним PoP, а не повільним рукостисканням з вами. (Самому світлу потрібно близько 100 мс, щоб пройти навколо світу через волокно, а для встановлення з'єднання TCP потрібно три пакети передавати туди-сюди. SSL вимагає трьох зворотних поїздок ).


1
У мене було спокуса поставити +1, але тоді у вашому другому абзаці є це неправильне зауваження про світло, яке займає лише 10 мс, щоб обійти півсвіту. 10 мс швидкості світла у вакуумі становить 3000 км, а 10 мс швидкості світла у волокні - не набагато більше 2000 км; півдорога навколо світу (вздовж поверхні) становить 20 000 км. Отже, це було б 100 мс --- якби тільки твоє волокно йшло безпосередньо з Лондона до Сіднея, а не могло обійти Африку морем або пройти довгий шлях Гаваями ...
піраміди

@pyramids Ви маєте рацію, або я це друкував, або просто дурив. Буде оновлено.
mjs
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.