Lorsque le code s'exécute, il peut en effet envoyer et recevoir des messages normalement .
🎜Mais après l'exécution de ce codependant un moment, erreur de délai d'attente d'E/S. 🎜🎜🎜🎜🎜Il s'agit en fait d'un problème qui a été étudié récemment. J'ai trouvé que ce piège était peut-être plus facile à surmonter, j'ai donc simplifié le code ici. 🎜🎜Lephénomène qui se produit dans la production réelle est,golang est en cours de lancementhttpLorsqu'il est appelé, bien que http.Transport définit 3sdélai d'expiration, Rapport d'erreur de délai d'attente d'E/S. 🎜🎜Mais en regardant les services en aval, j'ai découvert que les services en aval étaient en fait100 ms a été renvoyé. 🎜🎜🎜🎜
Dépannage
L'analyse des modifications du corps du message correspondant au protocole réseau à cinq couches
est très étrange. Il est évident que le traitement de l'affichage côté serveur prend du temps100 ms< /code>, et le délai d'expiration du client est défini sur <code style="font-size: Heherit;line-height: Heherit;padding: 2px 4px;border-radius: 4px;margin-right: 2px ;margin-left: 2px ;color: rgb(255, 82, 82);background: rgb(248, 248, 248);">3s, pourquoi une erreur de délai d'attente se produit-elle Qu'en est-il du délai d'expiration des E/S ? 100ms,且客户端超时设的是3s, 怎么就出现超时报错 i/o timeout 呢?
Parce que les journaux imprimés par le serveur ne sont en fait que des journaux imprimés par la
couche d'application du serveur. Mais une fois que la couche d'application client a envoyé les données, elles passent également par la couche de transport, la couche réseau, la couche liaison de données et la couche physique du client, puis passent par la couche physique, la couche liaison de données, la couche réseau et la couche transport du serveur vers le service La couche application à la fin
. La couche d'application serveur prend
100 ms, puis revient au chemin d'origine. Le reste3s-100ms
Peut-être qu'il est dépensé sur différentes couches dans l'ensemble du processus. Par exemple, lorsque le réseau n'est pas bon, la couche transport TCP perd vigoureusement les paquets et les retransmet. Il n'y a aucun problème avec le réseau L'ensemble du processus d'envoi et de réception du client. au serveur prend environ du temps. C'est-à-dire Environ 100 ms. Un délai d'attente se produit en raison de problèmes de logique de traitement du client.
🎜🎜🎜Généralement, lorsque vous rencontrez des problèmes, dans la plupart des cas, ce n'est pas un problème avec le réseau sous-jacent, soupçonnez simplement qu'il s'agit de votre propre problème🎜. Si vous n'abandonnez pas, prenez un sac et. jetez un oeil. 🎜🎜🎜🎜🎜🎜Résultat de capture de paquets🎜🎜🎜Analyse, depuis le début des trois poignées de main (🎜L'endroit où est dessinée la case rouge🎜). 🎜
Protocole HTTP de , 82, 82);background: rgb(248, 248, 248);">Avant la version 1.0, la valeur par défaut était Connexion courte , une connexion TCP sera établie à chaque fois qu'une requête est faite. Envoyez et recevez des données. Puis déconnectez-vous. 🎜🎜La connexion TCP est une poignée de main à trois à chaque fois. Chaque déconnexion nécessite quatre vagues. 🎜🎜En fait, il n'est pas nécessaire d'établir une nouvelle connexion à chaque fois. Il suffit que la connexion établie ne soit pas déconnectée et réutilisée à chaque envoi de données. 🎜🎜Ainsi, le protocole HTTP a changé de Après la version 1.1, il sera utilisé par défaut Connexion longue</code >. Pour des informations spécifiques, veuillez consulter cet article précédent. 🎜🎜Puis<code style="font-size: hériter; ligne-hauteur: hériter; rembourrage: 2px 4px; border-radius: 4px; marge-droite: 2px; marge-gauche: 2px; couleur: rgb (255, 82 , 82);background: rgb(248, 248, 248);">la bibliothèque standard golang est également compatible avec cette implémentation. 🎜🎜En établissant un pool de connexions, ciblez Chaque nom de domaine établit une longue connexion TCP, telle que http://baidu.com et http://golang.com sont deux noms de domaine différents. 🎜🎜Première visitehttp://baidu.com Une connexion sera établie lors de l'utilisation du nom de domaine. Après utilisation, il sera placé dans le pool de connexions inactif et téléchargé à nouveau : rgb(255, 82, 82);background: rgb(248, 248, 248);">http://baidu.com récupérera la connexion du pool de connexionsRéutiliser. 🎜Réutiliser les connexions longues
Une digression : Cela explique aussi la dernière question de cet article, pourquoi il faut mettre l'accent sur le même nom de domaine : un nom de domaine établira une connexion, et une connexion correspondra à Une goroutine de lecture et une goroutine d'écriture. Parce qu'il s'agit du même nom de domaine, il sera divulgué à la fin -left: 2px;color: rgb(255, 82, 82);background: rgb(248, 248, 248);">3 goroutines, s'il s'agit de noms de domaine différents, cela fuira1+2*N coroutines, N est le nombre de noms de domaine. 3个goroutine,如果不同域名的话,那就会泄漏 1+2*N 个协程,N就是域名数。
🎜🎜🎜 Supposons que la première requête consiste à 100 ms, chaque requête est terminée http://baidu.com Après tout, placez-le dans le pool de connexions et continuez à le réutiliser la prochaine fois. RépétezLorsque 30 requêtes sont effectuées, la connexion a été utilisée depuis le moment de l'établissement jusqu'au retour du service3000 ms, qui atteint juste le seuil de délai d'attente défini de 🎜3s🎜, le client signalera un délai d'attente à ce moment-làdélai d'expiration des E/S . 🎜🎜Bien qu'à ce moment-là, le serveur ait effectivement dépensé 100 ms, mais ne supporte pas le devant也就是说只要通过 http.Transport 设置了 err = conn.SetDeadline(time.Now().Add(time.Second * 3)),并且你用了长连接,哪怕服务端处理再快,客户端设置的超时再长,总有一刻,你的程序会报超时错误。
Ne pas utiliser Le délai d'expiration défini dans http.Transport est le délai d'expiration de la connexion, pas le délai d'expiration de la demande. Sinon, inexplicable erreur de délai d'attente io. http.Transport中设置超时,那是连接的超时,不是请求的超时。否则可能会出现莫名 io timeout报错。
请求的超时在创建client
Délai d'expiration de la demande lors de la création : rgb(255, 82, 82); background: rgb(248, 248, 248);">client. 🎜🎜🎜
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!
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn