Поддерживает ли HTML WebSockets открытое соединение для каждого клиента? Это масштаб?

Мне любопытно, есть ли у кого-нибудь информация о масштабируемости HTML WebSockets. Для всего, что я прочитал, кажется, что каждый клиент будет поддерживать открытую линию связи с сервером. Мне просто интересно, как эти масштабы и сколько открытых соединений WebSocket может обрабатывать сервер. Возможно, оставляя эти связи открытыми, в действительности не проблема, но похоже, что это так.

Ответ 1

В большинстве случаев WebSockets, вероятно, будет лучше, чем AJAX/HTML-запросы. Однако это не означает, что WebSockets заменяет все виды использования AJAX/HTML.

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

Когда-либо пытались настроить веб-сервер для поддержки десятков тысяч одновременных клиентов AJAX? Измените эти клиенты на клиенты WebSockets, и это может быть возможно.

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

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

  • Как правило, серверы HTTP настроены для регистрации начала и завершения каждого HTTP-запроса, занимающего время диска и процессора. Становится стандартным регистрировать начало и завершение данных WebSockets, но в то время как соединение WebSockets, осуществляющее двустороннюю передачу, не будет иметь дополнительных затрат на ведение журнала (за исключением приложения/услуги, если оно предназначено для этого).

  • Как правило, интерактивные приложения, использующие AJAX, либо непрерывно проводят опрос, либо используют какой-то механизм долгого опроса. WebSockets - это гораздо более чистый (и более низкий ресурс) способ создания более event'd-модели, где сервер и клиент уведомляют друг друга, когда им есть что-то сообщить о существующем соединении.

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

Основным преимуществом WebSockets будет использование более низких латентных подключений для интерактивных веб-приложений. Он будет лучше масштабироваться и потреблять меньше ресурсов сервера, чем HTTP AJAX/long-poll (при условии, что приложение/сервер спроектирован должным образом), но более низкая латентность IMO является основным преимуществом WebSockets, поскольку это позволит использовать новые классы веб-приложений с текущими накладными расходами и задержкой AJAX/long-poll.

Как только стандарт WebSockets станет более финализированным и будет иметь более широкую поддержку, имеет смысл использовать его для большинства новых интерактивных веб-приложений, которым необходимо часто общаться с сервером. Для существующих интерактивных веб-приложений это будет действительно зависеть от того, насколько хорошо работает текущая модель AJAX/long-poll. Усилия по конвертации будут носить нетривиальный характер, поэтому во многих случаях стоимость просто не принесет пользы.

Обновление

Полезная ссылка: 600k одновременных подключений к сети на AWS с использованием Node.js

Ответ 2

Просто пояснение: количество клиентских подключений, поддерживаемых сервером, не имеет ничего общего с портами в этом сценарии, поскольку сервер [обычно] прослушивает только соединения WS/WSS на одном порту. Я думаю, что другие комментаторы хотели ссылаться на файловые дескрипторы. Вы можете установить максимальное количество дескрипторов файлов достаточно высоко, но тогда вам нужно следить за размерами буфера сокетов, добавляя их для каждого открытого сокета TCP/IP. Здесь дополнительная информация: https://serverfault.com/questions/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

Что касается уменьшенной задержки через WS против HTTP, это правда, потому что больше не существует синтаксического разбора HTTP-заголовков за начальное рукопожатие WS. Кроме того, по мере того, как все больше и больше пакетов успешно отправляются, окно перегрузки TCP расширяется, эффективно сокращая время отклика.

Ответ 3

Любой современный единственный сервер способен сервер тысячи клиентов сразу. Его HTTP-серверное программное обеспечение должно быть ориентировано на события (IOCP) (мы уже не в старом Apache одном соединении = одно нить/процессное уравнение). Даже HTTP-сервер, построенный в Windows (http.sys), ориентирован на IOCP и очень эффективен (работает в режиме ядра). С этой точки зрения не будет большой разницы при масштабировании между WebSockets и обычным HTTP-соединением. Одно TCP/IP-соединение использует небольшой ресурс (намного меньше потока), а современная ОС оптимизирована для обработки множества параллельных подключений: WebSockets и HTTP - это всего лишь протоколы уровня OSI 7, наследующие от этих спецификаций TCP/IP.

Но, из эксперимента, я видел две основные проблемы с WebSockets:

  • Они не поддерживают CDN;
  • У них есть потенциальные проблемы с безопасностью.

Поэтому я бы порекомендовал следующее для любого проекта:

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

На практике все приложения WebSockets недостаточно масштабируются. Просто используйте WebSockets для того, для чего они были разработаны: push-уведомления от сервера к клиенту.

О потенциальных проблемах использования WebSockets:

1. Рассмотрите возможность использования CDN

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

Конечно, вы не будете помещать все свои данные в свой CDN-кеш, но на практике много общего контента не будет часто меняться. Я подозреваю, что 80% ресурсов REST могут быть кэшированы... Даже один минутный (или 30 секунд) тайм-аут истечения CDN может быть достаточным для того, чтобы дать вашему центральному серверу новую жизнь и значительно повысить оперативность реагирования приложений, поскольку CDN может географически настроены...

Насколько мне известно, в CDN еще нет поддержки WebSockets, и я подозреваю, что этого никогда не будет. WebSockets являются statefull, тогда как HTTP не имеет апатридов, поэтому его легко кэшировать. Фактически, чтобы сделать WebSockets CDN-friendly, вам может потребоваться переключиться на безстоящий RESTful подход... который больше не будет WebSockets.

2. Проблемы безопасности

У WebSockets есть потенциальные проблемы с безопасностью, особенно в отношении DOS-атак. Для иллюстрации новых уязвимостей безопасности см. этот набор слайдов и этот веб-кит.

WebSockets не исключает возможности проверки пакетов на уровне уровня приложений OSI 7, который в настоящее время является довольно стандартным для любой безопасности бизнеса. Фактически, WebSockets делает запущенную передачу, поэтому может быть серьезное нарушение утечки безопасности.

Ответ 4

Подумайте об этом так: что дешевле, поддерживая открытое соединение или открывая новое соединение для каждого запроса (с накладными расходами на переговоры, помните TCP).

Конечно, это зависит от приложения, но для долгосрочных подключений в реальном времени (например, чата AJAX) гораздо лучше отключить соединение.

Максимальное количество подключений будет ограничено максимальным количеством бесплатных портов для сокетов.

Ответ 5

У меня создается впечатление, что все эти уровни протокола были изобретены из-за отсутствия базовых знаний. Как устойчивые соединения и объединение миллионов дескрипторов могут масштабироваться лучше, чем увольнять-увольнять, я сомневаюсь в этом. Эти ребята когда-либо писали простой TCP-сервер в C, чтобы узнать, какие масштабы лучше? Я так не думаю.