Сделать так, чтобы веб-сокетов поддерживать открытое соединение для каждого клиента? Разве это масштаб?


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

5 141

5 ответов:

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

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

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

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

  • каждое соединение HTTP несет много багажа, который не используется большую часть времени: куки, тип контента, длина conetent, user-agent, идентификатор сервера, дата, последнее изменение и т. д. Как только соединение 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 параллельные подключения websocket на AWS с помощью узла.js

просто уточнение: количество клиентских подключений, которые может поддерживать сервер, не имеет ничего общего с портами в этом сценарии, поскольку сервер [обычно] прослушивает только соединения 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 расширяется, эффективно уменьшая RTT.

любой современный одиночный сервер способен к серверу тысячи клиентов одновременно. Его программное обеспечение HTTP-сервера просто должно быть ориентировано на события (IOCP) (мы больше не находимся в старом Apache one connection = one thread/process equation). Даже 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 для того, для чего они были разработаны: push-уведомления с сервера на сервер клиент.

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

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

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

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

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

2. Вопросы безопасности

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

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

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

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

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

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