¿HTML WebSockets mantiene una conexión abierta para cada cliente? ¿Esta escala?

Tengo curiosidad por saber si alguien tiene información sobre la escalabilidad de HTML WebSockets. Por todo lo que he leído, parece que cada cliente mantendrá una línea abierta de comunicación con el servidor. Me pregunto cómo se escapan esas escalas y cuántas conexiones abiertas de WebSocket puede manejar un servidor. Quizás dejar esas conexiones abiertas no es un problema en realidad, pero se siente como es.

En la mayoría de los casos, WebSockets probablemente escalará mejor que las solicitudes AJAX / HTML. Sin embargo, eso no significa que WebSockets sea un reemplazo para todos los usos de AJAX / HTML.

Cada conexión TCP en sí misma consume muy poco en términos de recursos del servidor. A menudo, la configuración de la conexión puede ser costosa, pero mantener una conexión inactiva es casi gratuita. La primera limitación que generalmente se encuentra es la cantidad máxima de descriptores de archivos (los sockets consumen descriptores de archivos) que pueden abrirse simultáneamente. Esto a menudo se predetermina a 1024 pero puede configurarse fácilmente más alto.

¿Alguna vez ha intentado configurar un servidor web para admitir decenas de miles de clientes AJAX simultáneos? Cambie esos clientes a clientes de WebSockets y podría ser factible.

Las conexiones HTTP, si bien no crean archivos abiertos o consumen números de puertos durante un período prolongado, son más costosas en casi cualquier otra forma:

  • Cada conexión HTTP lleva una gran cantidad de equipaje que no se usa la mayor parte del tiempo: cookies, tipo de contenido, longitud de conexión, agente de usuario, identificación del servidor, fecha, última modificación, etc. Una vez que se establece una conexión WebSockets, solo el los datos requeridos por la aplicación deben enviarse de ida y vuelta.

  • Por lo general, los servidores HTTP están configurados para registrar el inicio y la finalización de cada solicitud HTTP que ocupa el disco y el tiempo de CPU. Se convertirá en estándar para registrar el inicio y la finalización de los datos de WebSockets, pero mientras la conexión WebSockets realiza la transferencia dúplex, no habrá ninguna tara adicional de registro (excepto por la aplicación / servicio si está diseñado para hacerlo).

  • Normalmente, las aplicaciones interactivas que usan AJAX sondean continuamente o usan algún tipo de mecanismo de larga encuesta. WebSockets es una forma mucho más limpia (y de menor recurso) de realizar un modelo más avanzado en el que el servidor y el cliente se notifican mutuamente cuando tienen algo que informar a través de la conexión existente.

  • La mayoría de los servidores web populares en producción tienen un conjunto de procesos (o subprocesos) para manejar las solicitudes HTTP. A medida que aumenta la presión, se boostá el tamaño del grupo porque cada proceso / subproceso maneja una solicitud HTTP a la vez. Cada proceso / subproceso adicional utiliza más memoria y la creación de nuevos procesos / subprocesos es bastante más costosa que la creación de nuevas conexiones de socket (que esos procesos / subprocesos aún tienen que hacer). La mayoría de los frameworks de servidor populares de WebSockets están yendo por la ruta del evento, que tiende a escalar y funcionar mejor.

El principal beneficio de WebSockets serán las conexiones de latencia más bajas para aplicaciones web interactivas. Escalará mejor y consumirá menos recursos de servidor que HTTP AJAX / Long-Poll (suponiendo que la aplicación / servidor está diseñado correctamente), pero la latencia más baja de la OMI es el principal beneficio de WebSockets porque permitirá nuevas clases de aplicaciones web que no son posibles con la sobrecarga actual y la latencia de AJAX / larga encuesta.

Una vez que el estándar WebSockets esté más finalizado y tenga un soporte más amplio, tendrá sentido usarlo para la mayoría de las nuevas aplicaciones web interactivas que necesitan comunicarse frecuentemente con el servidor. Para las aplicaciones web interactivas existentes, realmente dependerá de qué tan bien esté funcionando el modelo AJAX / Long-Poll actual. El esfuerzo de conversión no será trivial, por lo que en muchos casos el costo no valdrá la pena.

Actualización :

Enlace útil: 600k conexiones concurrentes websocket en AWS usando Node.js

Solo una aclaración: el número de conexiones de cliente que un servidor puede admitir no tiene nada que ver con los puertos en este escenario, ya que el servidor [típicamente] solo está escuchando conexiones WS / WSS en un solo puerto. Creo que lo que los otros comentaristas querían mencionar eran los descriptores de archivos. Puede establecer el número máximo de descriptores de archivos bastante alto, pero luego debe tener cuidado con los tamaños de búfer de sockets que se sumn para cada socket TCP / IP abierto. Aquí hay información adicional: https://serverfault.com/questions/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

En cuanto a la latencia disminuida a través de WS frente a HTTP, es cierto ya que no hay más análisis de encabezados HTTP más allá del inicio de sesión inicial de WS. Además, a medida que se envían cada vez más paquetes, la ventana de congestión de TCP se amplía, reduciendo efectivamente el RTT.

Cualquier servidor único moderno puede server a miles de clientes a la vez . Su software de servidor HTTP tiene que ser orientado por eventos (IOCP) (no estamos en la vieja conexión Apache one = una ecuación thread / process). Incluso el servidor HTTP construido en Windows (http.sys) está orientado a IOCP y es muy eficiente (se ejecuta en modo kernel). Desde este punto de vista, no habrá mucha diferencia al escalar entre WebSockets y la conexión HTTP regular. Una conexión TCP / IP usa un pequeño recurso (mucho menos que un hilo) y el sistema operativo moderno está optimizado para manejar muchas conexiones simultáneas: WebSockets y HTTP son solo protocolos de capa de aplicación OSI 7, que heredan de estas especificaciones de TCP / IP.

Pero, por experimento, he visto dos problemas principales con WebSockets:

  1. No son compatibles con CDN;
  2. Tienen posibles problemas de seguridad.

Así que recomendaría lo siguiente, para cualquier proyecto:

  • Use WebSockets solo para notificaciones de clientes (con un mecanismo alternativo para largas sondeos, hay muchas bibliotecas disponibles);
  • Use RESTful / JSON para todos los demás datos, utilizando un CDN o proxies para caché.

En la práctica, las aplicaciones completas de WebSockets no se escalan bien. Solo use WebSockets para lo que fueron diseñados: enviar notificaciones desde el servidor al cliente.

Acerca de los posibles problemas de usar WebSockets:

1. Considere usar un CDN

Hoy (casi 4 años después), el escalamiento web implica el uso de front-ends de Content Delivery Network (CDN), no solo para contenido estático (html, css, js) sino también para sus datos de aplicación (JSON) .

Por supuesto, no va a poner todos sus datos en su caché CDN, pero en la práctica, un montón de contenido común no cambiará a menudo. Sospecho que el 80% de sus recursos REST pueden almacenarse en caché … Incluso un minuto (o 30 segundos) de expiración del tiempo de espera de CDN puede ser suficiente para darle una nueva vida a su servidor central y mejorar la capacidad de respuesta de la aplicación, ya que CDN puede estar geográficamente sintonizado …

Que yo sepa, no hay soporte WebSockets en CDN todavía, y sospecho que nunca lo será. Los WebSockets son statefull, mientras que HTTP es sin estado, por lo que se almacena en caché fácilmente. De hecho, para hacer que WebSockets sea compatible con CDN, es posible que deba cambiar a un enfoque RESTful sin estado … que ya no sería WebSockets.

2. Cuestiones de seguridad

WebSockets tiene posibles problemas de seguridad, especialmente sobre ataques DOS. Para ver una ilustración sobre las nuevas vulnerabilidades de seguridad, consulte este conjunto de diapositivas y este boleto de webkit .

Los WebSockets evitan cualquier posibilidad de inspección de paquetes en el nivel de la capa de aplicación OSI 7, que ahora es bastante estándar en cualquier seguridad empresarial. De hecho, WebSockets ofusca la transmisión, por lo que puede ser una brecha importante en la fuga de seguridad.

Piénselo de esta manera: qué es más económico, mantener una conexión abierta o abrir una nueva conexión para cada solicitud (con la sobrecarga de negociación al hacerlo, recuerde que es TCP).

Por supuesto, depende de la aplicación, pero para las conexiones en tiempo real a largo plazo (por ejemplo, un chat AJAX) es mucho mejor mantener la conexión abierta.

El número máximo de conexiones estará limitado por la cantidad máxima de puertos libres para los sockets.

No, no escala, da un tremendo trabajo a los switches de rutas intermedias. Luego, en el lado del servidor, las fallas de página (debe mantener todos esos descriptores) están alcanzando valores altos, y aumenta el tiempo para llevar un recurso al área de trabajo. Estos son en su mayoría servidores escritos JAVA y podría ser más rápido mantener esos archivos de sockets y luego destruir / crear uno. Cuando ejecuta dicho servidor en una máquina, cualquier otro proceso ya no se puede mover.