Maison  >  Article  >  interface Web  >  Analyser les facteurs courants qui affectent les performances http

Analyser les facteurs courants qui affectent les performances http

little bottle
little bottleavant
2019-04-28 10:24:202586parcourir

Le contenu principal de cet article est de présenter les facteurs communs qui affectent les performances HTTP. Il a une certaine valeur de référence. Les amis intéressés peuvent en apprendre davantage.

Les performances HTTP dont nous discutons ici sont basées sur le modèle le plus simple, qui est les performances HTTP d'un seul serveur. Bien sûr, elles sont également applicables aux clusters d'équilibrage de charge à grande échelle. Après tout, ce cluster l'est. également composé de plusieurs serveurs HTTP. De plus, nous excluons également que la charge sur le client ou le serveur lui-même soit trop élevée ou que le logiciel implémentant le protocole HTTP utilise des modèles d'E/S différents. De plus, nous ignorons également les défauts dans le processus de résolution DNS et dans le développement de l'application Web lui-même.

Du point de vue du modèle TCP/IP, la couche inférieure de HTTP est la couche TCP, donc les performances de HTTP dépendent en grande partie des performances de TCP. Bien sûr, s'il s'agit de HTTPS, le TLS/. Une couche SSL doit être ajoutée, mais c'est possible. Il est certain que les performances du HTTPS sont nettement moins bonnes que celles du HTTP. Le processus de communication ne sera pas abordé ici. Bref, plus il y a de couches, plus la perte de performances sera importante. être.

Dans les conditions ci-dessus, les facteurs les plus courants qui affectent les performances HTTP incluent :

  • L'établissement d'une connexion TCP, qui est la phase de négociation à trois

  • Démarrage lent TCP

  • Accusé de réception différé TCP

  • Algorithme Nagle

  • Accumulation TIME_WAIT et port épuisé

  • Port du serveur épuisé

  • Le nombre de fichiers ouverts dans le processus HTTP du serveur a atteint le maximum

Établissement de la connexion TCP

Habituellement, si le réseau est stable, l'établissement de la connexion TCP ne prendra pas beaucoup de temps et le processus de négociation à trois sera terminé dans un délai raisonnable Cependant, étant donné que HTTP est sans état et qu'il s'agit d'une connexion courte, une fois la session HTTP acceptée, la connexion TCP sera généralement déconnectée, ce qui signifie qu'il y aura de nombreuses sessions HTTP par rapport à la connexion HTTP. Session HTTP, la négociation à trois voies TCP pour établir la connexion prendra trop de temps. Bien sûr, vous pouvez utiliser Réutiliser les connexions existantes pour réduire le nombre de fois d'établissement de connexion TCP.

Démarrage lent de TCP

Méthode de contrôle de la congestion TCP1, dans la phase de transmission initiale après l'établissement de TCP, la vitesse de transmission maximale de la connexion sera limitée si le. la transmission des données est réussie, la vitesse de transmission sera progressivement augmentée à l'avenir, ce qu'on appelle le démarrage lent TCP. Le démarrage lent limite le nombre de paquets IP 2 pouvant être transmis à la fois. Alors pourquoi y a-t-il un démarrage lent ? L'objectif principal est d'éviter que le réseau ne soit paralysé en raison d'une transmission de données à grande échelle. Un lien très important dans la transmission de données sur Internet est le routeur, et le routeur lui-même n'est pas rapide. Internet peut être envoyé et nécessiter un routage et un transfert. Si la quantité de données arrivant au routeur au cours d'une certaine période de temps est bien supérieure à la quantité envoyée, le routeur supprimera les paquets de données lorsque le cache local sera épuisé. Ce comportement est appelé congestion. Un routeur dans cette situation affectera de nombreux liens et peut conduire à une paralysie généralisée dans les cas graves. Par conséquent, toute partie dans la communication TCP doit effectuer un contrôle de congestion, et le démarrage lent est l'un des algorithmes ou mécanismes de contrôle de congestion.
Vous imaginez une situation. Nous savons que TCP dispose d'un mécanisme de retransmission. Supposons qu'un routeur du réseau subisse une perte de paquets à grande échelle en raison d'une congestion. En tant qu'expéditeur de données, sa pile de protocole TCP détectera certainement cette situation. Ensuite, il démarrera le mécanisme de retransmission TCP, et l'expéditeur affecté par le routeur doit être plus que vous. Ensuite, un grand nombre de piles de protocoles TCP de l'expéditeur ont commencé à retransmettre, ce qui équivaut à envoyer plus de données sur le réseau Bao initialement encombré. , cela revient à jeter de l’huile sur le feu.

Grâce à la description ci-dessus, on peut conclure que même dans un environnement réseau normal, comme l'expéditeur de messages HTTP et chaque demande d'établissement d'une connexion TCP sera affecté par un démarrage lent, alors selon HTTP, un une connexion courte est une session Elle sera déconnectée une fois terminée. Vous pouvez imaginer que le client a lancé une requête HTTP et vient d'obtenir une ressource sur la page Web, et que le HTTP a été déconnecté avant. le processus de démarrage lent de TCP est terminé. Ensuite, les autres pages Web Les ressources suivantes continueront à établir des connexions TCP, et chaque connexion TCP aura une phase de démarrage lent. Cette performance peut être imaginée, donc afin d'améliorer les performances, nous pouvons activer HTTP. connexions persistantes, qui est le keepalive mentionné plus tard.

De plus, nous savons qu'il existe le concept de fenêtre dans TCP. Cette fenêtre existe à la fois sur l'expéditeur et sur le destinataire. Le rôle de la fenêtre garantit que l'expéditeur et le destinataire deviennent ordonnés lors de la gestion du paquet. D'un autre côté, lorsque plusieurs paquets peuvent être envoyés sur la base d'une séquence pour améliorer le débit ; un autre point est que la taille de la fenêtre peut être ajustée, le but est d'empêcher l'expéditeur d'envoyer des données plus rapidement que le destinataire ne peut les recevoir. Bien que la fenêtre résolve le problème de la vitesse de communication en double envoi, d'autres périphériques réseau passeront par le réseau. Comment l'expéditeur connaît-il la capacité de réception du routeur ? Il y a donc le contrôle de la congestion introduit ci-dessus.

Confirmation différée TCP

Tout d'abord, vous devez savoir ce qu'est une confirmation. Cela signifie que l'expéditeur envoie un segment TCP au destinataire. Après l'avoir reçu, le destinataire doit le renvoyer. une confirmation pour indiquer la réception, si l'expéditeur ne reçoit pas la confirmation dans un certain délai, le segment TCP doit être renvoyé.

Les messages de confirmation sont généralement relativement petits, c'est-à-dire qu'un groupe IP peut transporter plusieurs messages de confirmation, donc afin d'éviter d'envoyer trop de petits messages, le destinataire attendra et verra lors du renvoi du message de confirmation. Y en a-t-il un autre. données envoyées au destinataire ? Si tel est le cas, rassemblez le message de confirmation et les données dans un segment TCP et envoyez-le. S'il n'y a pas d'autres données à envoyer dans un certain laps de temps, généralement 100 à 200 millisecondes, puis envoyez le message de confirmation dans un paquet séparé. En fait, le but est de réduire autant que possible la charge du réseau.

Un exemple courant est la logistique. La capacité de chargement d'un camion est certaine. S'il a une capacité de chargement de 10 tonnes et que vous voyagez d'une ville A à une ville B, vous voulez absolument qu'il soit aussi plein. que possible au lieu de venir avec un petit colis, vous vous levez immédiatement et conduisez vers la ville B.

TCP est donc conçu pour ne pas renvoyer une confirmation ACK immédiatement lorsqu'un paquet de données arrive. Il s'accumule généralement dans le cache pendant un certain temps, s'il y a encore des données dans la même direction, il les renverra. confirmation ACK précédente Mais vous ne pouvez pas attendre trop longtemps, sinon l'autre partie pensera que le paquet a été perdu et déclenchera une retransmission de la part de l'autre partie.

Différents systèmes d'exploitation auront des opinions différentes sur l'opportunité et la manière d'utiliser la confirmation différée. Par exemple, Linux peut être activé ou désactivé, cela signifie confirmer chacun au fur et à mesure.

Il convient de noter que son activation ou le nombre de millisecondes à définir dépend du scénario. Par exemple, dans les scénarios de jeux en ligne, la confirmation doit être effectuée dès que possible et une confirmation différée peut être utilisée pour les sessions SSH.

Pour HTTP, nous pouvons désactiver ou ajuster la confirmation différée TCP.

Algorithme Nagle

Cet algorithme est en fait conçu pour améliorer l'utilisation des paquets IP et réduire la charge du réseau. Il implique toujours de petits paquets et des paquets de taille réelle (selon les normes Ethernet, la MTU est de 1 500 octets par message). , et tout message inférieur à 1 500 est considéré comme un message de taille non complète), mais quelle que soit la taille du petit message, il ne fera pas moins de 40 octets, car l'en-tête IP et l'en-tête TCP occupent chacun 20 octets. Si vous envoyez un petit message de 50 octets, cela signifie en fait qu'il y a trop peu de données valides. Tout comme l'accusé de réception retardé, les paquets de petite taille ne constituent pas un gros problème dans le LAN, mais affectent principalement le WAN.

Cet algorithme est en fait le suivant: si l'expéditeur a envoyé un message dans la connexion TCP actuelle mais n'a pas encore reçu de confirmation, alors si l'expéditeur a encore de petits messages à envoyer, il ne peut pas les envoyer. dans le tampon pour attendre la confirmation du message précédemment envoyé. Après avoir reçu la confirmation, l'expéditeur collectera les petits messages dans la même direction dans le cache et les assemblera en un seul message pour l'envoi. En fait, cela signifie que plus le destinataire renvoie rapidement la confirmation ACK, plus l’expéditeur peut envoyer les données rapidement.

Parlons maintenant des problèmes que la combinaison de la confirmation retardée et de l’algorithme de Nagle entraînera. En fait, il est facile de voir qu'en raison du retard de la confirmation, le destinataire accumulera des confirmations ACK pendant un certain temps et l'expéditeur ne continuera pas à envoyer les données non complètes restantes s'il ne reçoit pas d'ACK pendant. cette période. Paquets (les données sont divisées en plusieurs paquets IP. Le nombre de paquets de données de réponse à envoyer par l'expéditeur ne peut pas être un multiple entier de 1 500. Il y a une forte probabilité que certaines données à la fin des données soient petites. -taille des paquets IP), vous pouvez donc voir. La contradiction ici est que ce type de problème affectera les performances de transmission dans la transmission TCP. Ensuite, HTTP dépend de TCP, donc cela affectera naturellement les performances HTTP. Habituellement, nous désactiverons l'algorithme sur le. côté serveur. Nous pouvons le désactiver sur le système d'exploitation ou en HTTP. Définissez TCP_NODELAY dans le programme pour désactiver cet algorithme. Par exemple, dans Nginx, vous pouvez utiliser tcp_nodelay on; pour le désactiver.

Accumulation de TIME_WAIT et épuisement des ports3

Il s'agit de la partie qui est le client ou de la partie qui ferme activement la connexion TCP, bien que le serveur puisse également prendre le initiative Initier la fermeture, mais ce dont nous discutons ici, ce sont les performances HTTP. En raison des caractéristiques des connexions HTTP, le client initie généralement la fermeture active

Le client initie une requête HTTP (ici c'est pour une ressource spécifique). demande au lieu d'ouvrir ce qu'on appelle une page d'accueil. Une page d'accueil a N ressources, donc N requêtes HTTP seront lancées.) Une fois cette requête terminée, la connexion TCP sera déconnectée et l'état TCP de la connexion sur le client apparaîtra. . Un état appelé TIME_WAIT De cet état à l'arrêt final, il faut généralement 2MSL4 Nous savons que lorsque le client accède au service HTTP du serveur, il utilisera son propre port aléatoire à bits élevés pour. connectez-vous au port 80 ou 443 du serveur pour établir une communication HTTP (son essence est la communication TCP), ce qui signifie que le nombre de ports disponibles sur le client sera consommé bien que le client se déconnecte, ce port aléatoire sera cependant libéré après. le client se déconnecte activement, l'état TCP Pendant la période 2MSL entre TIME_WAIT et CLOSED réel, le port aléatoire ne sera pas utilisé (si le client initie à nouveau l'accès HTTP au même serveur. L'un de ses objectifs est d'empêcher les données sales sur le). même socket TCP. De la conclusion ci-dessus, nous savons que si l'accès HTTP du client au serveur est trop intensif, la vitesse d'utilisation du port peut être supérieure à la vitesse de libération du port, ce qui finira par conduire à l'échec de l'établissement d'une connexion car il n'y a pas de connexion aléatoire disponible. port.

Comme nous l'avons dit ci-dessus, le client ferme généralement la connexion activement,

Explication détaillée TCP/IP Volume 1 Deuxième édition, P442, le dernier paragraphe indique que pour les applications interactives, le client effectue généralement une opération d'arrêt actif et entre dans l'état TIME_WAIT, et le serveur effectue généralement une opération d'arrêt passive. et il n'entrera pas directement dans l'état TIME_WAIT.

Cependant, si le serveur Web a activé le maintien en vie, le serveur s'arrêtera automatiquement lorsque le délai d'attente sera atteint. (Je ne dis pas que l'explication détaillée de TCP/IP est fausse ici, mais c'est principalement pour TCP dans cette section, et n'introduit pas HTTP, et cela dit généralement plutôt que nécessairement)

J'utilise Nginx a été testé et keepalive_timeout 65s; a été défini dans le fichier de configuration. Le paramètre par défaut de Nginx est 75s. Le définir sur 0 signifie désactiver keepalive, comme indiqué ci-dessous :

Analyser les facteurs courants qui affectent les performances http

J'utilise. ci-dessous Le navigateur Chrom accède à la page d'accueil fournie par Nginx par défaut et surveille l'ensemble du processus de communication via le programme de capture de paquets, comme indiqué ci-dessous :

Analyser les facteurs courants qui affectent les performances http

Comme le montre ce qui précède figure, les données effectives sont transmises. Une fois terminé, une communication marquée Keep-Alive apparaît au milieu et le serveur se déconnecte activement après aucune demande dans les 65 secondes. Dans ce cas, vous verrez l'état TIME_WAIT sur le serveur Nginx.

Le port du serveur est épuisé

Certaines personnes disent que Nginx écoute 80 ou 443. Le client se connecte toujours à ce port. Comment le serveur peut-il mettre fin au port ? Tout comme l'image ci-dessous (ignorez TIME_WAIT dans l'image, la raison en a été mentionnée ci-dessus et est causée par le paramètre keepalive_timeout de Nginx)

Analyser les facteurs courants qui affectent les performances http

En fait, cela dépend de Nginx En mode de fonctionnement, lorsque nous utilisons Nginx, nous le faisons généralement fonctionner en mode proxy, ce qui signifie que les ressources ou données réelles se trouvent sur l'application Web back-end, telle que Tomcat. La caractéristique du mode proxy est que le serveur proxy accède au backend pour obtenir des données au nom de l'utilisateur. À ce stade, par rapport au serveur backend, Nginx est un client. À ce stade, Nginx utilisera un port aléatoire pour. lancez une requête vers le backend et le système est disponible. La plage de ports aléatoires est certaine. Vous pouvez utiliser la commande sysctl net.ipv4.ip_local_port_range pour afficher la plage de ports aléatoires sur le serveur.

Grâce à la confirmation différée, à l'algorithme Nagle et au mode proxy que nous avons introduits précédemment, Nginx agit en tant que client du backend et utilise un port aléatoire pour se connecter au backend, ce qui signifie que le risque d'épuisement des ports sur le serveur côté existe. Une vitesse de libération aléatoire du port peut se produire si elle est inférieure à la vitesse d'établissement d'une connexion avec le backend. Cependant, cette situation ne se produit généralement pas. Du moins, je n'ai pas trouvé ce phénomène dans Nginx de notre entreprise. Parce que premièrement, les ressources statiques sont sur CDN ; deuxièmement, la plupart du backend utilise des interfaces REST pour fournir l'authentification des utilisateurs ou les opérations de base de données. En fait, ces opérations sont fondamentalement très rapides s'il n'y a pas de goulots d'étranglement sur le backend. Mais cela dit, si le backend présente réellement un goulot d'étranglement et que le coût d'extension ou de modification de l'architecture est relativement élevé, alors ce que vous devez faire face à une grande quantité de concurrence est de limiter le flux pour éviter que le backend ne soit tué.

Le nombre de fichiers ouverts par le processus HTTP côté serveur atteint le maximum

Nous avons dit que la communication HTTP repose sur des connexions TCP. Une connexion TCP est un socket pour les systèmes de type Unix. , ouverture d'un socket Le mot est d'ouvrir un fichier S'il y a 100 demandes de connexion au serveur, alors une fois la connexion établie avec succès, le serveur ouvrira 100 fichiers, et le nombre de fichiers qu'un processus peut ouvrir dans le. Le système Linux est limité ulimit -f, donc si ce réglage est trop petit, cela affectera également la connexion HTTP. Pour Nginx ou d'autres programmes HTTP exécutés en mode proxy, une connexion ouvre généralement deux sockets et occupe deux fichiers (sauf lorsqu'elle atteint le cache local de Nginx ou que Nginx renvoie directement des données). Par conséquent, le nombre de fichiers pouvant être ouverts par le processus du serveur proxy doit également être plus grand.

Connexion persistante Keepalive

Tout d'abord, nous devons savoir que keepalive peut être défini sur deux niveaux, et les deux niveaux ont des significations différentes. Le keepalive de TCP est un mécanisme de détection.Par exemple, les informations de battement de cœur que nous disons souvent indiquent que l'autre partie est toujours en ligne. Ces informations de battement de cœur sont envoyées avec un intervalle de temps, ce qui signifie que la connexion TCP entre eux doit toujours rester ouverte. -alive en HTTP est un mécanisme permettant de réutiliser les connexions TCP pour éviter l'établissement fréquent de connexions TCP. Vous devez donc comprendre que TCP Keepalive et HTTP Keep-alive ne sont pas la même chose.

Mécanisme de maintien HTTP

Les connexions non persistantes déconnecteront la connexion TCP après chaque transaction HTTP, et la prochaine transaction HTTP rétablira la connexion TCP. Ce n'est évidemment pas le cas. Il s'agit d'un mécanisme efficace, donc dans les versions améliorées de HTTP/1.1 et HTTP/1.0, HTTP est autorisé à garder la connexion TCP ouverte après la fin de la transaction, afin que les transactions HTTP ultérieures puissent réutiliser la connexion jusqu'à ce que le client ou Le serveur ferme activement la connexion. Les connexions persistantes réduisent le nombre d'établissements de connexions TCP et minimisent également les restrictions de trafic provoquées par un démarrage lent de TCP.

Tutoriels associés : Tutoriel vidéo HTTP

Analyser les facteurs courants qui affectent les performances http

Regardez à nouveau cette image Le keepalive_timeout 65s dans l'image est configuré pour garder http activé. La fonctionnalité active a défini le délai d'attente à 65 secondes. En fait, une autre option plus importante est keepalive_requests 100;, qui indique le nombre maximum de requêtes HTTP pouvant être initiées par la même connexion TCP.

Keep-alive n'est pas utilisé par défaut dans HTTP/1.0 Lorsque le client envoie une requête HTTP, il doit inclure l'en-tête Connection: Keep-alive pour essayer d'activer keep-alive. , il ne sera pas utilisé. Toutes les demandes seront faites sous la forme habituelle, et les informations Connection: Keep-alive seront également incluses dans l'en-tête de réponse si le serveur le prend en charge.

Keep-alive est utilisé par défaut dans HTTP/1.1 Sauf indication contraire, toutes les connexions sont persistantes. Si vous souhaitez fermer la connexion après la fin d'une transaction, l'en-tête de réponse HTTP doit contenir l'en-tête Connection: CLose, sinon la connexion restera toujours ouverte. Bien sûr, elle ne peut pas toujours être ouverte et les connexions inactives doivent également être fermées. comme Nginx ci-dessus, le paramètre est le même que pour maintenir une connexion inactive pendant 65 secondes maximum. Après cela, le serveur déconnectera activement la connexion.

TCP keepalive

Il n'y a pas de commutateur unifié pour activer ou désactiver la fonction TCP keepalive sous Linux Vérifiez les paramètres keepalive du systèmesysctl -a | grep tcp_keepalive Si vous ne l'avez pas modifié, alors dans Centos. Il affichera sur le système :

net.ipv4.tcp_keepalive_intvl = 75   # 两次探测直接间隔多少秒
net.ipv4.tcp_keepalive_probes = 9   # 探测频率
net.ipv4.tcp_keepalive_time = 7200  # 表示多长时间进行一次探测,单位秒,这里也就是2小时

Selon les paramètres par défaut, la signification générale de ce qui précède est de détecter une fois toutes les 2 heures si la première détection échoue, puis de détecter à nouveau après 75 secondes. 9 fois, il prendra l'initiative.

Comment activer Keepalive au niveau TCP sur Nginx. Il existe une instruction dans Nginx appelée listen C'est une instruction dans la section serveur qui est utilisée pour définir le port sur lequel Nginx écoute. il y a d'autres paramètres derrière cela. Utilisé pour définir les propriétés du socket, regardez les paramètres suivants :

# 表示开启,TCP的keepalive参数使用系统默认的
listen       80 default_server so_keepalive=on;
# 表示显式关闭TCP的keepalive
listen       80 default_server so_keepalive=off;
# 表示开启,设置30分钟探测一次,探测间隔使用系统默认设置,总共探测10次,这里的设
# 置将会覆盖上面系统默认设置
listen       80 default_server so_keepalive=30m::10;

Donc, la définition de ce so_keepalive sur Nginx dépend du scénario spécifique. Ne confondez pas TCP keepalive avec HTTP keepalive , car. Nginx n'active pas so_keepalive, cela n'affectera pas votre requête HTTP utilisant la fonctionnalité keep-alive. S'il existe un périphérique d'équilibrage de charge entre le client et Nginx directement ou entre Nginx et le serveur backend et que les réponses et les demandes passeront par ce périphérique d'équilibrage de charge, vous devez alors faire attention à so_keepalive. Par exemple, il ne sera pas affecté en mode routage direct de LVS, car la réponse ne passe pas par
LVS. Cependant, il faut y faire attention s'il est en mode NAT, car LVS a aussi une durée. pour maintenir la session TCP. Si la durée est inférieure à la durée du backend pour renvoyer les données, alors LVS déconnectera la connexion TCP avant que le client ne reçoive les données.


  1. Le contrôle de congestion TCP a certains algorithmes, notamment le démarrage lent TCP, l'évitement de congestion et d'autres algorithmes ↩

  2. Certains est également appelé fragmentation IP, mais tout cela signifie la même chose. Quant à savoir pourquoi la fragmentation est simplement limitée par la couche de liaison de données, différentes liaisons de données ont des MTU Ethernet différentes, soit 1 500 octets. Le MTU de FDDI est une autre taille En considérant uniquement la couche IP, le paquet de données IP maximum est de 65 535 octets ↩

  3. À la page P90 du "Guide faisant autorité HTTP", il n'est pas très clair si. cette situation est relative au client ou au serveur, car elle risque très probablement d'être mal comprise. Bien sûr, cela ne signifie pas que le serveur ne manquera pas de ports, je l'ai donc ajouté ici 2 éléments de contenu↩

  4. La durée la plus longue ne dépassera pas 2 minutes↩

Tutoriels associés :

Tutoriel vidéo HTTP

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer