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

160

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

Райан Монтгомери
источник
1
Нет такого понятия, как HTML WebSocket. Вы имеете в виду HTTP WebSocket.
маркиз Лорн

Ответы:

209

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

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

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

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

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

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

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

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

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

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

Обновление :

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

канак
источник
4
Отличный ансер. Спасибо, что нашли время ответить.
Райан Монтгомери
7
Я до сих пор не знаю, как масштабировать, когда вы врезаетесь в стену. Это правда, что WebSockets потребляет меньше ресурсов (они масштабируются по вертикали), но HTTP отлично подходит для горизонтального масштабирования. Я могу теоретически добавлять серверы, чтобы масштабировать бесконечно. Меня всегда смущало, как масштабировать, когда вы используете емкость одного блока. Мысли?
Шон Кларк Хесс
6
@Sean. WebSockets не обязательно хуже при горизонтальном масштабировании. Он просто открывает новые приложения, которые не всегда легко масштабируются. Например, для обслуживания статических данных группа серверов WebSocket будет масштабироваться так же хорошо (или лучше), как группа серверов HTTP. Игру в реальном времени с малой задержкой трудно масштабировать независимо от транспорта (и это просто невозможно с использованием HTTP). Реальный вопрос в том, насколько хорошо вы масштабируете данные / приложения. Если это масштабируется, то ваш выбор HTTP против WebSockets должен основываться на других факторах: задержка, параметры развертывания, поддержка браузера и т. Д.
kanaka
2
Одно исправление - TCP-соединение состоит из IP-адреса назначения и порта назначения. Это означает, что ограничение на ± 64 КБ портов фактически ТОЛЬКО для одного клиента. Теоретически, сервер может иметь любое количество открытых соединений, ограниченных ТОЛЬКО его оборудованием.
Ризон
@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-сервера просто ориентировано на Event-Driven (IOCP) (мы больше не находимся в старом соединении Apache - одно соединение = одно уравнение потока / процесса). Даже встроенный в Windows HTTP-сервер (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 года спустя) веб-масштабирование включает использование внешних интерфейсов Content Delivery Network (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, но ориентирован на передачу потоковых данных и т. Д. Через веб-сокеты или какую-то еще неизвестную технологию.
Quixver
8

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

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

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

kaoD
источник
Вы можете оставить соединение открытым без использования WebSocket (благодаря опции keep alive HTTP / 1.1). Я не уверен, что понимаю вашу мысль здесь.
Арно Бушез
1
+1. Люди, как правило, забывают, что настройка TCP-соединения включает в себя syn / ack / ack, а TLS требует большего количества циклов обмена ключами.
Quixver
1
@ArnaudBouchez check en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 WebSockets открыты столько, сколько вы хотите, и не являются хакерскими (например, длинные опросы и другие альтернативы).
КаоД
-5

Нет, он не масштабируется, дает огромную работу переключателям промежуточных маршрутов. Затем на стороне сервера ошибки страниц (вы должны сохранить все эти дескрипторы) достигают высоких значений, и время для ввода ресурса в рабочую область увеличивается. В основном это написанные на JAVA серверы, и может быть быстрее удержать эти gazilions сокетов, чем уничтожить / создать один. Когда вы запускаете такой сервер на машине, любой другой процесс больше не может двигаться.

user2195463
источник