Donc, selon l'auteur haproxy, qui en sait une ou deux sur http:
Keep-alive a été inventé pour réduire l'utilisation du processeur sur les serveurs lorsque les processeurs étaient 100 fois plus lents. Mais ce qui n'est pas dit, c'est que les connexions persistantes consomment beaucoup de mémoire tout en n'étant utilisables par personne sauf le client qui les a ouvertes. Aujourd'hui en 2009, les processeurs sont très bon marché et la mémoire est encore limitée à quelques gigaoctets par l'architecture ou le prix. Si un site a besoin de keep-alive, il y a un vrai problème. Les sites très chargés désactivent souvent la fonction Keep-Alive pour prendre en charge le nombre maximum de clients simultanés. Le vrai inconvénient de ne pas avoir de keep-alive est une latence légèrement accrue pour récupérer des objets. Les navigateurs doublent le nombre de connexions simultanées sur les sites non-keepalive pour compenser cela.
(à partir de http://haproxy.1wt.eu/ )
Est-ce conforme à l'expérience d'autres peuples? c'est-à-dire sans keep-alive - le résultat est-il à peine perceptible maintenant? (il vaut probablement la peine de noter qu'avec les websockets, etc. - une connexion est maintenue "ouverte" quel que soit l'état de maintien en vie de toute façon - pour des applications très réactives). L'effet est-il plus important pour les personnes éloignées du serveur ou s'il y a de nombreux artefacts à charger à partir du même hôte lors du chargement d'une page? (Je pense que des choses comme CSS, images et JS proviennent de plus en plus de CDN compatibles avec le cache).
Pensées?
(Je ne sais pas si c'est une chose serverfault.com, mais je ne vais pas traverser le message jusqu'à ce que quelqu'un me dise de le déplacer là-bas).
la source
Réponses:
Hé puisque je suis l'auteur de cette citation, je vais répondre :-)
Il y a deux gros problèmes sur les grands sites: les connexions simultanées et la latence. Les connexions simultanées sont causées par des clients lents qui mettent du temps à télécharger le contenu et par des états de connexion inactifs. Ces états de connexion inactifs sont causés par la réutilisation de la connexion pour récupérer plusieurs objets, appelés keep-alive, qui sont encore augmentés par la latence. Lorsque le client est très proche du serveur, il peut faire un usage intensif de la connexion et s'assurer qu'il n'est presque jamais inactif. Cependant, lorsque la séquence se termine, personne ne se soucie de fermer rapidement le canal et la connexion reste ouverte et inutilisée pendant longtemps. C'est la raison pour laquelle de nombreuses personnes suggèrent d'utiliser un délai de maintien en vie très faible. Sur certains serveurs comme Apache, le délai d'expiration le plus bas que vous pouvez définir est d'une seconde, et il est souvent beaucoup trop long pour supporter des charges élevées: si vous avez 20000 clients devant vous et qu'ils récupèrent en moyenne un objet toutes les secondes, vous aurez ces 20000 connexions établies en permanence. 20000 connexions simultanées sur un serveur polyvalent comme Apache sont énormes, nécessiteront entre 32 et 64 Go de RAM selon les modules chargés, et vous ne pouvez probablement pas espérer aller beaucoup plus haut même en ajoutant de la RAM. En pratique, pour 20000 clients, vous pouvez même voir 40000 à 60000 connexions simultanées sur le serveur car les navigateurs essaieront de configurer 2 à 3 connexions s'ils ont de nombreux objets à récupérer. et vous ne pouvez probablement pas espérer aller beaucoup plus haut même en ajoutant de la RAM. En pratique, pour 20000 clients, vous pouvez même voir 40000 à 60000 connexions simultanées sur le serveur car les navigateurs essaieront de configurer 2 à 3 connexions s'ils ont de nombreux objets à récupérer. et vous ne pouvez probablement pas espérer aller beaucoup plus haut même en ajoutant de la RAM. En pratique, pour 20000 clients, vous pouvez même voir 40000 à 60000 connexions simultanées sur le serveur car les navigateurs essaieront de configurer 2 à 3 connexions s'ils ont de nombreux objets à récupérer.
Si vous fermez la connexion après chaque objet, le nombre de connexions simultanées diminuera considérablement. En effet, il baissera d'un facteur correspondant au temps moyen de téléchargement d'un objet par le temps entre les objets. Si vous avez besoin de 50 ms pour télécharger un objet (une photo miniature, un bouton, etc ...), et que vous téléchargez en moyenne 1 objet par seconde comme ci-dessus, alors vous n'aurez que 0,05 connexion par client, soit seulement 1000 connexions simultanées pour 20000 clients.
Maintenant, le temps d'établir de nouvelles connexions va compter. Les clients éloignés connaîtront une latence désagréable. Dans le passé, les navigateurs utilisaient de grandes quantités de connexions simultanées lorsque le maintien en vie était désactivé. Je me souviens des chiffres de 4 sur MSIE et de 8 sur Netscape. Cela aurait vraiment divisé la latence moyenne par objet par autant. Maintenant que le keep-alive est présent partout, nous ne voyons plus ce nombre élevé, car cela augmente encore la charge sur les serveurs distants, et les navigateurs prennent soin de protéger l'infrastructure d'Internet.
Cela signifie qu'avec les navigateurs actuels, il est plus difficile d'obtenir les services non-keep-alive aussi réactifs que les services keep-alive. De plus, certains navigateurs (par exemple: Opera) utilisent des heuristiques pour essayer d'utiliser le pipelinining. Le pipelining est un moyen efficace d'utiliser le keep-alive, car il élimine presque la latence en envoyant plusieurs demandes sans attendre de réponse. Je l'ai essayé sur une page avec 100 petites photos, et le premier accès est environ deux fois plus rapide que sans keep-alive, mais le prochain accès est environ 8 fois plus rapide, car les réponses sont si petites que seule la latence compte (seulement "304" réponses).
Je dirais que, idéalement, nous devrions avoir des paramètres réglables dans les navigateurs pour leur permettre de maintenir les connexions actives entre les objets récupérés et de les supprimer immédiatement lorsque la page est terminée. Mais nous ne voyons pas cela malheureusement.
Pour cette raison, certains sites qui ont besoin d'installer des serveurs à usage général tels qu'Apache sur la face avant et qui doivent prendre en charge de grandes quantités de clients doivent généralement désactiver le keep-alive. Et pour forcer les navigateurs à augmenter le nombre de connexions, ils utilisent plusieurs noms de domaine afin que les téléchargements puissent être parallélisés. C'est particulièrement problématique sur les sites utilisant intensivement SSL car la configuration de la connexion est encore plus élevée car il y a un aller-retour supplémentaire.
Ce qui est plus couramment observé de nos jours, c'est que ces sites préfèrent installer des frontaux légers tels que haproxy ou nginx, qui n'ont aucun problème à gérer des dizaines à des centaines de milliers de connexions simultanées, ils activent le keep-alive côté client et le désactivent sur le Côté Apache. De ce côté, le coût d'établissement d'une connexion est presque nul en termes de CPU, et pas du tout perceptible en termes de temps. De cette façon, cela offre le meilleur des deux mondes: une faible latence due à la persistance avec des délais d'expiration très faibles côté client et un faible nombre de connexions côté serveur. Tout le monde est content :-)
Certains produits commerciaux améliorent encore cela en réutilisant les connexions entre l'équilibreur de charge avant et le serveur et en multiplexant toutes les connexions client sur eux. Lorsque les serveurs sont proches du LB, le gain n'est pas beaucoup plus élevé que la solution précédente, mais il faudra souvent des adaptations sur l'application pour s'assurer qu'il n'y a pas de risque de croisement de session entre utilisateurs en raison du partage inattendu d'une connexion entre plusieurs utilisateurs . En théorie, cela ne devrait jamais arriver. La réalité est bien différente :-)
la source
Depuis que cela a été écrit (et publié ici sur stackoverflow), nous avons maintenant des serveurs tels que nginx qui gagnent en popularité.
nginx, par exemple, peut contenir 10 000 connexions persistantes ouvertes en un seul processus avec seulement 2,5 Mo (mégaoctets) de RAM. En fait, il est facile de maintenir ouvertes plusieurs milliers de connexions avec très peu de RAM, et les seules limites que vous atteindrez seront d'autres limites telles que le nombre de descripteurs de fichiers ouverts ou de connexions TCP.
Keep-alive était un problème non pas à cause d'un problème avec la spécification keep-alive elle-même, mais à cause du modèle de mise à l'échelle basé sur les processus d'Apache et des keep-alives piratés dans un serveur dont l'architecture n'a pas été conçue pour l'accueillir.
Apache Prefork + mod_php + keep-alives est particulièrement problématique. Il s'agit d'un modèle dans lequel chaque connexion continuera à occuper toute la RAM occupée par un processus PHP, même si elle est complètement inactive et ne reste ouverte qu'en tant que keep-alive. Ce n'est pas évolutif. Mais les serveurs n'ont pas besoin d'être conçus de cette façon - il n'y a aucune raison particulière pour qu'un serveur ait besoin de garder chaque connexion persistante dans un processus séparé (surtout pas lorsque chaque processus de ce type a un interpréteur PHP complet). PHP-FPM et un modèle de traitement de serveur basé sur les événements comme celui de nginx résolvent le problème avec élégance.
Mise à jour 2015:
SPDY et HTTP / 2 remplacent la fonctionnalité de maintien en vie de HTTP par quelque chose d'encore mieux: la possibilité non seulement de maintenir une connexion active et de faire plusieurs requêtes et réponses, mais aussi de les multiplexer, afin que les réponses puissent être envoyées dans n'importe quel ordre , et en parallèle, plutôt que seulement dans l'ordre où ils ont été demandés. Cela empêche les réponses lentes de bloquer les plus rapides et supprime la tentation pour les navigateurs de maintenir ouvertes plusieurs connexions parallèles vers un seul serveur. Ces technologies mettent en évidence les insuffisances de l'approche mod_php et les avantages de quelque chose comme un serveur Web basé sur les événements (ou à tout le moins, multi-thread) couplé séparément à quelque chose comme PHP-FPM.
la source
ma compréhension était que cela n'avait pas grand-chose à voir avec le processeur, mais la latence dans l'ouverture de sockets répétées à l'autre bout du monde. même si vous avez une bande passante infinie, la latence de connexion ralentira l'ensemble du processus. amplifié si votre page contient des dizaines d'objets. même une connexion persistante a une latence requête / réponse, mais elle est réduite lorsque vous avez 2 sockets car en moyenne, l'une devrait diffuser des données tandis que l'autre pourrait bloquer. De plus, un routeur ne supposera jamais qu'une socket se connecte avant de vous laisser écrire dessus. Il a besoin de la poignée de main aller-retour complète. encore une fois, je ne prétends pas être un expert, mais c'est ainsi que je l'ai toujours vu. ce qui serait vraiment cool, c'est un protocole entièrement ASYNC (non, pas un protocole complètement malade).
la source
Des keep-alives très longs peuvent être utiles si vous utilisez un CDN "origin pull" tel que CloudFront ou CloudFlare. En fait, cela peut s'avérer plus rapide que pas de CDN, même si vous diffusez un contenu complètement dynamique.
Si vous avez une longue durée de vie telle que chaque PoP a fondamentalement une connexion permanente à votre serveur, la première fois que les utilisateurs visitent votre site, ils peuvent faire une poignée de main TCP rapide avec leur PoP local au lieu d'une lente prise de contact avec vous. (La lumière elle-même prend environ 100 ms pour parcourir la moitié du monde via la fibre, et l'établissement d'une connexion TCP nécessite la transmission de trois paquets dans les deux sens. SSL nécessite trois allers-retours .)
la source