Чи підтримують HTML WebSockets відкрите з'єднання для кожного клієнта? Це масштаб?


159

Мені цікаво, чи є у когось інформація про масштабованість HTML WebSockets. З усього, що я прочитав, схоже, що кожен клієнт буде підтримувати відкриту лінію зв'язку з сервером. Мені просто цікаво, як це масштабує і скільки відкритих підключень WebSocket сервер може працювати. Можливо, залишити ці зв’язки відкритими не проблема в реальності, але відчувається, що є.


1
Не існує такого поняття, як HTML WebSocket. Ви маєте на увазі HTTP WebSocket.
Маркіз Лорн

Відповіді:


209

У більшості способів WebSockets, ймовірно, масштабується краще, ніж запити AJAX / HTML. Однак це не означає, що WebSockets є заміною для всіх видів використання AJAX / HTML.

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

Ви коли-небудь намагалися налаштувати веб-сервер для підтримки десятків тисяч одночасних клієнтів AJAX? Замініть цих клієнтів на клієнтів WebSockets, і це просто може бути здійснено.

HTTP-з’єднання, хоча вони не створюють відкритих файлів і не споживають номерів портів протягом тривалого періоду, дорожчі майже будь-яким іншим способом:

  • Кожне HTTP-з'єднання містить багато багажу, який не використовується більшою частиною часу: файли cookie, тип вмісту, довжина контенту, користувальницький агент, ідентифікатор сервера, дата, остання зміна тощо. Після встановлення з’єднання WebSockets, лише дані, потрібні додатку, потрібно надсилати назад і назад.

  • Зазвичай сервери HTTP налаштовані для реєстрації запуску та завершення кожного запиту HTTP, який займає час диска та процесора. Стандартом буде реєструвати початок та завершення даних WebSockets, але в той час, як з'єднання WebSockets здійснює двосторонню передачу, додаткових журналів не буде накладено (крім програми / служби, якщо це призначено для цього).

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

  • Більшість популярних веб-серверів у виробництві мають пул процесів (або потоків) для обробки HTTP-запитів. Зі збільшенням тиску розмір пулу збільшуватиметься, оскільки кожен процес / потік обробляє один HTTP-запит одночасно. Кожен додатковий процес / потік використовує більше пам’яті, а створення нових процесів / потоків є дещо дорожчим, ніж створення нових з'єднань з сокетами (що ці процеси / потоки все ще мають робити). Більшість популярних фреймворків сервера WebSockets проходять маршрут подій, який має тенденцію до масштабності та ефективнішої роботи.

Основною перевагою WebSockets буде нижча затримка з'єднань для інтерактивних веб-додатків. Він буде масштабуватись краще та споживатиме менше серверних ресурсів, ніж HTTP AJAX / тривалий опитування (якщо припустити, що програма / сервер розроблений належним чином), але нижча затримка IMO є головною перевагою WebSockets, оскільки це дозволить отримати нові класи веб-додатків, які неможливі з поточним накладним та затримкою AJAX / тривалого опитування.

Після того, як стандарт WebSockets стане більш доопрацьованим і отримає більш широку підтримку, його буде доцільно використовувати для більшості нових інтерактивних веб-додатків, яким потрібно часто спілкуватися з сервером. Для існуючих інтерактивних веб-додатків це дійсно залежатиме від того, наскільки добре працює поточна модель AJAX / long-опитування. Зусилля по перетворенню будуть нетривіальними, тому в багатьох випадках вартість просто не буде корисною.

Оновлення :

Корисне посилання: 600k одночасних підключень веб-сокетів на AWS за допомогою Node.js


4
Awesome anser. Дякуємо, що знайшли час для відповіді.
Райан Монтгомері

7
Я все ще не знаю, як масштабувати, коли ти вдаришся про стіну. Це правда, що WebSockets споживають менше ресурсів (вони масштабуються вертикально), але HTTP чудово підходить для масштабування по горизонталі. Я теоретично можу додавати сервери для масштабування нескінченно. Мене завжди бентежить питання щодо масштабування, коли ви використовуєте ємність одного поля. Думки?
Шон Кларк Хесс

6
@Sean. WebSockets не обов'язково гірше при горизонтальному масштабуванні. Це просто відкриває нові програми, які не обов'язково масштабувати так легко. Наприклад, для обслуговування статичних даних купа серверів WebSocket може масштабуватись так само (або краще), ніж купа серверів HTTP. Гра в режимі реального часу з низьким запізненням складно масштабувати незалежно від транспорту (і це просто не реально за допомогою HTTP). Справжнє питання полягає в тому, наскільки добре ви масштабуєте дані / програми. Якщо це масштаби, то ваш вибір HTTP проти WebSockets повинен базуватися на інших чинниках: затримці, опціях розгортання, підтримці браузера тощо
kanaka

2
Одне виправлення - з'єднання TCP складається з ip призначення та порту призначення. Це означає, що ліміт ± 64k портів насправді ТІЛЬКИ для одного клієнта. Теоретично сервер може мати будь-яку кількість відкритих підключень, обмежених ТОЛЬКО своїм обладнанням.
Різон

@Rizon, це правда. Я оновив відповідь і змінив обмеження відкритого порту і замість цього згадав обмеження дескриптора файлу, яке саме те, до якого часто стикаються люди.
канака

36

Тільки уточнення: кількість підключень клієнтів, які може підтримувати сервер, не має нічого спільного з портами в цьому сценарії, оскільки сервер [зазвичай] слухає лише WS / WSS-з'єднання на одному порту. Я думаю, що інші коментатори мали на увазі посилання на дескриптори файлів. Ви можете встановити максимальну кількість дескрипторів файлів досить високою, але тоді вам слід буде стежити за розмірами буфера сокета, що додає для кожного відкритого TCP / IP-сокета. Ось додаткова інформація: /server/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

Що стосується зменшеної затримки через WS проти HTTP, то це правда, оскільки немає більше розбору заголовків HTTP за межами початкового рукостискання WS. Крім того, у міру успішного надсилання все більшої кількості пакетів вікно TCP перевантаження розширюється, що ефективно знижує RTT.


AFAIR є один вхідний порт, але завжди відкривається один вихідний порт для кожного з'єднання. Це лише одна частина проблеми C10k .
Арно Бушез

14

Будь-який сучасний єдиний сервер здатний обслуговувати тисячі клієнтів одночасно . Його HTTP-серверне програмне забезпечення повинно бути орієнтоване на події (IOCP) (ми не маємо в старому Apache одне з'єднання = один потік / рівняння процесу). Навіть сервер HTTP, вбудований у Windows (http.sys), орієнтований на IOCP і дуже ефективний (працює в режимі ядра). З цієї точки зору, не буде великої різниці в масштабуванні між WebSockets і звичайним HTTP-з'єднанням. Одне TCP / IP-з'єднання використовує трохи ресурсу (набагато менше, ніж потік), а сучасна ОС оптимізована для обробки багатьох одночасних з'єднань: WebSockets і HTTP - це просто протоколи прикладного рівня OSI 7, успадковані від цих специфікацій TCP / IP.

Але з експерименту я бачив дві основні проблеми з WebSockets:

  1. Вони не підтримують CDN;
  2. Вони мають потенційні проблеми безпеки.

Тому я рекомендую наступне для будь-якого проекту:

  • Використовуйте WebSockets лише для сповіщень клієнтів (з механізмом резервного резервування для довготривалого опитування - навколо них багато бібліотек);
  • Використовуйте RESTful / JSON для всіх інших даних, використовуючи CDN або проксі-сервери для кешу.

На практиці повноцінні програми WebSockets не масштабуються. Просто використовуйте WebSockets для того, для чого вони були розроблені: надсилати сповіщення з сервера на клієнта.

Про потенційні проблеми використання WebSockets:

1. Подумайте про використання CDN

Сьогодні (майже 4 роки пізніше) масштабування веб-сторінок передбачає використання передового кінця мережі доставки вмісту (CDN) не лише для статичного вмісту (html, css, js), а й даних ваших програм (JSON) .

Звичайно, ви не будете ставити всі свої дані в кеш-пам'ять CDN, але на практиці багато загального вмісту не змінюватиметься часто. Я підозрюю, що 80% ваших REST-ресурсів може бути кешоване ... Навіть однієї хвилини (або 30 секунд) часу закінчення терміну дії CDN може бути достатньо, щоб дати центральному серверу нову трансляцію та значно підвищити швидкість реагування додатків, оскільки CDN може бути географічно налаштованим ...

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

2. Питання безпеки

У WebSockets можливі проблеми з безпекою, особливо щодо DOS-атак. Для ілюстрації про нові вразливості безпеки дивіться цей набір слайдів і цей квиток на веб-кави .

WebSockets уникає будь-якого шансу перевірити пакет на рівні прикладного рівня OSI 7, який сьогодні є досить стандартним у будь-якій безпеці бізнесу. Насправді WebSockets робить передачу придушеною, тому може бути серйозним порушенням витоку безпеки.


2
@ArnaudBouchez - +1 за приємну експозицію на CDN. Швидке наступне запитання - що ви думаєте про доцільність мереж доставки подій? Відображається після CDN, але орієнтоване на доставку потокових даних тощо через веб-розетки чи якусь іншу, поки небачену технологію.
Кіксвер

8

Подумайте про це так: що дешевше, зберігати відкрите з'єднання або відкривати нове з'єднання для кожного запиту (маючи на увазі переговори про це, пам’ятайте, що це TCP.)

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

Максимальна кількість з'єднань буде обмежена максимальною кількістю вільних портів для розеток.


Ви можете залишати з'єднання відкритим, не використовуючи WebSocket (завдяки параметру HTTP / 1.1). Я не впевнений, що я тут розумію вашу думку.
Арно Бушез

1
+1. Люди, як правило, забувають, що налаштування TCP-з'єднання передбачає syn / ack / ack, а TLS вимагає більше туди і назад для обміну ключами.
Кіксвер

1
@ArnaudBouchez перевірити en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 WebSockets відкриті, доки ви не хочете, і не є хакерськими (наприклад, тривалий опитування та інші альтернативи).
якD

-5

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

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