Nous essayons de régler une application qui accepte les messages via TCP et utilise également TCP pour une partie de sa messagerie interne. Lors des tests de charge, nous avons constaté que le temps de réponse se dégradait considérablement (puis s'arrêtait complètement) à mesure que davantage de demandes simultanées étaient adressées au système. Pendant ce temps, nous voyons beaucoup de connexions TCP de statut TIME_WAIT
et quelqu'un a suggéré de réduire la variable d'environnement TIME_WAIT
de sa valeur par défaut de 60 secondes à 30.
De ce que je comprends , le paramètre TIME_WAIT
définit essentiellement le moment où une ressource TCP est à nouveau disponible pour le système après la fermeture de la connexion.
Je ne suis pas un "gars du réseau" et je connais très peu ces choses. J'ai besoin de beaucoup de ce qui est dans ce post lié, mais un peu "stupéfait".
TIME_WAIT
ne peut pas être définie sur 0, mais peut-elle être définie de manière sûre sur 5? Qu'en est-il de 10? Qu'est-ce qui détermine un paramètre "sûr" pour cette valeur?Une connexion TCP est spécifiée par le Tuple (IP source, port source, IP de destination, port de destination).
La raison pour laquelle il y a un état TIME_WAIT à la suite de l'arrêt de la session est qu'il peut toujours y avoir des paquets actifs hors du réseau sur le chemin qui les acheminent vers vous (ou de votre part et qui peuvent solliciter une réponse). Si vous recréez ce même Tuple et qu'un de ces paquets se présente, il sera traité comme un paquet valide pour votre connexion (et provoquera probablement une erreur en raison du séquencement).
Par conséquent, l'heure TIME_WAIT est généralement définie pour doubler l'âge maximal des paquets. Cette valeur correspond à l'âge maximum auquel vos paquets seront autorisés avant que le réseau les jette.
Cela garantit que, avant de pouvoir créer une connexion avec le même Tuple, tous les paquets appartenant aux incarnations précédentes de ce Tuple seront morts.
Cela dicte généralement la valeur minimale que vous devez utiliser. L'âge maximum des paquets est dicté par les propriétés du réseau, un exemple étant que les durées de vie des satellites sont supérieures à celles du réseau local, car les paquets ont encore beaucoup de chemin à parcourir.
En règle générale, seul l'état final qui émet une «fermeture active» doit passer à l'état TIME_WAIT. Donc, si possible, demandez à vos clients d’émettre la fermeture active, ce qui laissera TIME_WAIT sur le client et NON sur le serveur.
Voir ici: http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html et http://www.isi.edu/touch/pubs/infocomm99/infocomm99-web/ pour plus de détails (le dernier explique également pourquoi ce n'est pas toujours possible en raison de la conception du protocole qui ne prend pas en compte TIME_WAIT).
Pax est correct sur les raisons de TIME_WAIT et sur la raison pour laquelle vous devez faire attention à la réduction du paramètre par défaut.
Une meilleure solution consiste à modifier les numéros de port utilisés pour l'extrémité d'origine de vos sockets. Une fois que vous faites cela, vous ne vous souciez plus vraiment du temps d'attente pour les sockets individuels.
Pour les sockets d’écoute, vous pouvez utiliser SO_REUSEADDR pour permettre au socket d’écoute de se lier malgré les sockets TIME_WAIT restants.
Sous Windows, vous pouvez changer it via le registre :
; Set the TIME_WAIT delay to 30 seconds (0x1E)
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TCPIP\Parameters]
"TcpTimedWaitDelay"=dword:0000001E
définir tcp_reuse est plus utile que de changer time_wait, tant que vous avez le paramètre (noyaux 3.2 et supérieurs, malheureusement, toutes les versions de RHEL et de XenServer sont disqualifiées).
La suppression de la valeur, en particulier pour les utilisateurs connectés au VPN, peut entraîner une recréation constante des tunnels proxy sur la connexion sortante. Avec la configuration par défaut de Netscaler (XenServer), qui est inférieure à la configuration par défaut de Linux, Chrome devra parfois recréer le tunnel de proxy une douzaine de fois pour récupérer une page Web. Les applications qui ne réessayent pas, telles que Maven et Eclipse P2, échouent simplement.
Le motif initial du paramètre (éviter la duplication) a été rendu redondant par un RFC TCP qui spécifie l'inclusion d'horodatage sur toutes les demandes TCP.
J'ai été charge de tester une application serveur (sur Linux) en utilisant un programme de test avec 20 threads.
En 959 000 cycles de connexion/fermeture, j'avais 44 000 connexions échouées et plusieurs milliers de sockets dans TIME_WAIT.
J'ai mis SO_LINGER à 0 avant l'appel de clôture et lors des exécutions ultérieures du programme de test, aucun échec de connexion et moins de 20 sockets dans TIME_WAIT.