Les WebSockets HTML maintiennent-ils une connexion ouverte pour chaque client? Est-ce que cette échelle?

160

Je suis curieux de savoir si quelqu'un a des informations sur l'évolutivité des WebSockets HTML. Pour tout ce que j'ai lu, il semble que chaque client maintiendra une ligne de communication ouverte avec le serveur. Je me demande simplement comment cela évolue et combien de connexions WebSocket ouvertes un serveur peut gérer. Peut-être que laisser ces connexions ouvertes n'est pas un problème en réalité, mais c'est comme si c'était le cas.

Ryan Montgomery
la source
1
Il n'existe pas de WebSocket HTML. Vous voulez dire HTTP WebSocket.
Marquis of Lorne

Réponses:

209

Dans la plupart des cas, les WebSockets évolueront probablement mieux que les requêtes AJAX / HTML. Cependant, cela ne signifie pas que WebSockets remplace toutes les utilisations d'AJAX / HTML.

Chaque connexion TCP en elle-même consomme très peu de ressources serveur. La configuration de la connexion peut souvent être coûteuse, mais le maintien d'une connexion inactive est presque gratuit. La première limitation généralement rencontrée est le nombre maximum de descripteurs de fichiers (les sockets consomment des descripteurs de fichiers) qui peuvent être ouverts simultanément. La valeur par défaut est souvent 1024 mais peut facilement être configurée plus haut.

Avez-vous déjà essayé de configurer un serveur Web pour prendre en charge des dizaines de milliers de clients AJAX simultanés? Changez ces clients en clients WebSockets et cela pourrait être possible.

Les connexions HTTP, bien qu'elles ne créent pas de fichiers ouverts ou n'utilisent pas de numéros de port pendant une longue période, sont plus chères à peu près dans tous les autres cas:

  • Chaque connexion HTTP transporte beaucoup de bagages qui ne sont pas utilisés la plupart du temps: cookies, type de contenu, longueur totale, user-agent, id du serveur, date, dernière modification, etc. Une fois la connexion WebSockets établie, seul le les données requises par l'application doivent être envoyées dans les deux sens.

  • En règle générale, les serveurs HTTP sont configurés pour enregistrer le début et la fin de chaque requête HTTP occupant le disque et le temps processeur. Il deviendra standard de consigner le début et l'achèvement des données WebSockets, mais pendant que la connexion WebSockets effectue un transfert duplex, il n'y aura pas de surcharge de journalisation supplémentaire (sauf par l'application / le service s'il est conçu pour le faire).

  • En règle générale, les applications interactives qui utilisent AJAX interrogent en permanence ou utilisent une sorte de mécanisme d'interrogation longue. WebSockets est un moyen beaucoup plus propre (et avec moins de ressources) de créer un modèle plus événementiel où le serveur et le client se notifient mutuellement lorsqu'ils ont quelque chose à signaler sur la connexion existante.

  • La plupart des serveurs Web populaires en production disposent d'un pool de processus (ou threads) pour gérer les requêtes HTTP. Lorsque la pression augmente, la taille du pool augmente car chaque processus / thread gère une requête HTTP à la fois. Chaque processus / thread supplémentaire utilise plus de mémoire et la création de nouveaux processus / threads coûte un peu plus cher que la création de nouvelles connexions de socket (ce que ces processus / threads doivent encore faire). La plupart des frameworks de serveurs WebSockets populaires suivent la route événementielle qui tend à évoluer et à mieux fonctionner.

Le principal avantage des WebSockets sera la réduction des connexions à latence pour les applications Web interactives. Il évoluera mieux et consommera moins de ressources serveur que HTTP AJAX / long-poll (en supposant que l'application / le serveur est conçu correctement), mais une latence inférieure IMO est le principal avantage de WebSockets car il permettra de nouvelles classes d'applications Web qui ne sont pas possibles avec la surcharge et la latence actuelles d'AJAX / long-poll.

Une fois que la norme WebSockets sera plus finalisée et bénéficiera d'une prise en charge plus large, il sera judicieux de l'utiliser pour la plupart des nouvelles applications Web interactives qui doivent communiquer fréquemment avec le serveur. Pour les applications Web interactives existantes, cela dépendra vraiment du bon fonctionnement du modèle AJAX / long-sondage actuel. L'effort de conversion ne sera pas trivial, donc dans de nombreux cas, le coût ne vaudra tout simplement pas l'avantage.

Mise à jour :

Lien utile: 600k connexions Websocket simultanées sur AWS à l'aide de Node.js

Kanaka
la source
4
Génial anser. Merci d'avoir pris le temps de répondre.
Ryan Montgomery
7
Je ne sais toujours pas comment évoluer une fois que vous avez heurté le mur. Il est vrai que les WebSockets consomment moins de ressources (ils évoluent verticalement), mais HTTP est idéal pour une mise à l'échelle horizontale. Je peux théoriquement ajouter des serveurs pour évoluer à l'infini. J'ai toujours été confus quant à la façon de faire évoluer une fois que vous avez utilisé la capacité d'une seule boîte. Pensées?
Sean Clark Hess
6
@Sean. WebSockets n'est pas nécessairement pire pour une mise à l'échelle horizontale. Cela ouvre simplement de nouvelles applications qui ne s'adaptent pas nécessairement aussi facilement. Par exemple, pour servir des données statiques, un groupe de serveurs WebSocket évoluerait aussi bien (ou mieux) qu'un groupe de serveurs HTTP. Un jeu en temps réel à faible latence est difficile à mettre à l'échelle quel que soit le transport (et ce n'est tout simplement pas vraiment faisable avec HTTP). La vraie question est de savoir dans quelle mesure vos données / applications évoluent. Si cela évolue, votre choix entre HTTP et WebSockets doit être basé sur d'autres facteurs: latence, options de déploiement, prise en charge du navigateur, etc.
kanaka
2
Une correction - une connexion TCP se compose de l'adresse IP de destination et du port de destination. Cela signifie que la limite de ± 64k ports est en fait UNIQUEMENT pour un seul client. Théoriquement, le serveur peut avoir n'importe quel nombre de connexions ouvertes, limité UNIQUEMENT par son matériel.
Rizon
@Rizon, c'est vrai. J'ai mis à jour la réponse et modifié la limitation du port ouvert et mentionné à la place la limitation du descripteur de fichier qui est celle que les gens rencontrent souvent en premier.
kanaka
36

Juste une clarification: le nombre de connexions client qu'un serveur peut prendre en charge n'a rien à voir avec les ports dans ce scénario, puisque le serveur n'écoute [généralement] que les connexions WS / WSS sur un seul port. Je pense que les autres commentateurs voulaient parler de descripteurs de fichiers. Vous pouvez définir le nombre maximum de descripteurs de fichier assez élevé, mais vous devez alors faire attention aux tailles de tampon de socket qui s'additionnent pour chaque socket TCP / IP ouvert. Voici quelques informations supplémentaires: /server/48717/practical-maximum-open-file-descriptors-ulimit-n-for-a-high-volume-system

En ce qui concerne la diminution de la latence via WS vs HTTP, c'est vrai car il n'y a plus d'analyse des en-têtes HTTP au-delà de la poignée de main WS initiale. De plus, à mesure que de plus en plus de paquets sont envoyés avec succès, la fenêtre de congestion TCP s'élargit, réduisant efficacement le RTT.

Michael
la source
AFAIR il y a un port entrant, mais toujours un port sortant ouvert pour chaque connexion. Ce n'est en fait qu'une partie du problème C10k .
Arnaud Bouchez
14

Tout serveur unique moderne est capable de servir des milliers de clients à la fois . Son logiciel de serveur HTTP doit juste être orienté Event-Driven (IOCP) (nous ne sommes plus dans l'ancien Apache une connexion = une équation thread / processus). Même le serveur HTTP intégré à Windows (http.sys) est orienté IOCP et très efficace (fonctionnant en mode noyau). De ce point de vue, il n'y aura pas beaucoup de différence au niveau de la mise à l'échelle entre les WebSockets et la connexion HTTP standard. Une connexion TCP / IP utilise peu de ressources (beaucoup moins qu'un thread) et les systèmes d'exploitation modernes sont optimisés pour gérer de nombreuses connexions simultanées: WebSockets et HTTP ne sont que des protocoles de couche application OSI 7, héritant de ces spécifications TCP / IP.

Mais, par expérience, j'ai vu deux problèmes principaux avec les WebSockets:

  1. Ils ne prennent pas en charge CDN;
  2. Ils ont des problèmes de sécurité potentiels.

Je recommanderais donc ce qui suit, pour tout projet:

  • Utilisez les WebSockets uniquement pour les notifications client (avec un mécanisme de secours pour l'interrogation longue - il y a beaucoup de bibliothèques autour);
  • Utilisez RESTful / JSON pour toutes les autres données, en utilisant un CDN ou des proxies pour le cache.

En pratique, les applications WebSockets complètes ne s'adaptent pas bien. Utilisez simplement les WebSockets pour ce pour quoi ils ont été conçus: pousser les notifications du serveur vers le client.

À propos des problèmes potentiels liés à l'utilisation des WebSockets:

1. Pensez à utiliser un CDN

Aujourd'hui (près de 4 ans plus tard), la mise à l'échelle du Web implique l'utilisation des frontaux du Content Delivery Network (CDN), non seulement pour le contenu statique (html, css, js) mais également pour les données de votre application (JSON) .

Bien sûr, vous ne mettrez pas toutes vos données sur votre cache CDN, mais dans la pratique, beaucoup de contenu commun ne changera pas souvent. Je soupçonne que 80% de vos ressources REST peuvent être mises en cache ... Même un délai d'expiration CDN d' une minute (ou 30 secondes) peut être suffisant pour donner à votre serveur central un nouveau live et améliorer considérablement la réactivité de l'application, car CDN peut être géographiquement à l'écoute ...

À ma connaissance, il n'y a pas encore de support WebSockets dans CDN, et je soupçonne que cela ne le serait jamais. Les WebSockets ont un état complet, alors que HTTP est sans état, il est donc beaucoup plus facile à mettre en cache. En fait, pour rendre WebSockets compatible CDN, vous devrez peut-être passer à une approche RESTful sans état ... qui ne serait plus WebSockets.

2. Problèmes de sécurité

Les WebSockets présentent des problèmes de sécurité potentiels, en particulier à propos des attaques DOS. Pour une illustration sur les nouvelles vulnérabilités de sécurité, consultez cet ensemble de diapositives et ce ticket de kit Web .

Les WebSockets évitent toute chance d'inspection des paquets au niveau de la couche application OSI 7, ce qui est aujourd'hui assez standard dans toute sécurité d'entreprise. En fait, WebSockets rend la transmission obscurcie, ce qui peut donc être une violation majeure de la fuite de sécurité.

Arnaud Bouchez
la source
2
@ArnaudBouchez - +1 pour la belle exposition sur CDN. Question de suivi rapide - que pensez-vous de la faisabilité des réseaux de livraison d'événements? Inspiré des CDN, mais orienté vers la diffusion de données en continu, etc. via des Websockets ou une autre technologie encore invisible.
quixver
8

Pensez-y de cette façon: ce qui est moins cher, garder une connexion ouverte ou ouvrir une nouvelle connexion pour chaque requête (avec la surcharge de négociation, rappelez-vous que c'est TCP.)

Bien sûr, cela dépend de l'application, mais pour les connexions en temps réel à long terme (par exemple un chat AJAX), il est préférable de garder la connexion ouverte.

Le nombre maximum de connexions sera plafonné par le nombre maximum de ports libres pour les sockets.

kaoD
la source
Vous pouvez garder la connexion ouverte sans utiliser de WebSocket (grâce à l'option keep alive de HTTP / 1.1). Je ne suis pas sûr de comprendre votre point de vue ici.
Arnaud Bouchez
1
+1. Les gens ont tendance à oublier que la configuration d'une connexion TCP implique un syn / ack / ack et TLS nécessite plus d'allers-retours pour l'échange de clés.
quixver
1
@ArnaudBouchez check en.wikipedia.org/wiki/HTTP_persistent_connection#HTTP_1.1 Les WebSockets sont ouverts aussi longtemps que vous le souhaitez et ne sont pas piratés (comme les longues interrogations et autres alternatives).
kaoD
-5

Non, il ne s'adapte pas, donne un travail énorme aux aiguillages de routes intermédiaires. Ensuite, côté serveur, les défauts de page (il faut garder tous ces descripteurs) atteignent des valeurs élevées, et le temps pour amener une ressource dans la zone de travail augmente. Ce sont pour la plupart des serveurs écrits en JAVA et il pourrait être plus rapide de conserver ces gazilions de sockets que de les détruire / en créer une. Lorsque vous exécutez un tel serveur sur une machine, tout autre processus ne peut plus bouger.

user2195463
la source