J'ai une application client/serveur (Java) que je migre de Solaris vers RH Linux. depuis que j'ai commencé à l'exécuter dans RH, j'ai remarqué quelques problèmes liés à la latence. J'ai réussi à isoler le problème qui ressemble à ceci:Migration de Solaris vers RH: problème de latence réseau, taille de la fenêtre tcp et autres paramètres tcp
- client envoie 5 messages (32 octets chacun) dans une rangée (même horodatage d'application) au serveur.
- messages d'échos de serveur.
- Le client reçoit des réponses et imprime le temps d'aller-retour pour chaque msg.
Solaris, tout va bien: je reçois TOUS 5 réponses en même temps, à peu près 80ms après avoir envoyé des messages originaux (serveur client & sont plusieurs milliers de miles de l'autre: mon ping RTT est 80ms, tout Ordinaire). En RH, les 3 premiers messages sont renvoyés normalement (ils arrivent 80ms après leur envoi), mais les 2 suivants arrivent 80ms plus tard (soit un RTT total de 160 ms).
le motif est toujours le même. clairement ressemblait à un problème TCP.
sur ma boîte de solaris, j'avais déjà configuré la pile tcp avec 2 options spécifiques:
- désactiver algorithme Nagle globalement
- ensemble tcp_deferred_acks_max à 0
sur RH, il est impossible pour désactiver globalement nagle, mais je l'ai désactivé sur toutes les sockets de mes applications (TCP_NODELAY).
donc je commencé à jouer avec tcpdump (sur la machine serveur), et comparé les deux sorties:
SOLARIS:
22 2.085645 client server TCP 56150 > 6006 [PSH, ACK] Seq=111 Ack=106 Win=66672 Len=22 "MSG_1 RCV"
23 2.085680 server client TCP 6006 > 56150 [ACK] Seq=106 Ack=133 Win=50400 Len=0
24 2.085908 client server TCP 56150 > 6006 [PSH, ACK] Seq=133 Ack=106 Win=66672 Len=22 "MSG_2 RCV"
25 2.085925 server client TCP 6006 > 56150 [ACK] Seq=106 Ack=155 Win=50400 Len=0
26 2.086175 client server TCP 56150 > 6006 [PSH, ACK] Seq=155 Ack=106 Win=66672 Len=22 "MSG_3 RCV"
27 2.086192 server client TCP 6006 > 56150 [ACK] Seq=106 Ack=177 Win=50400 Len=0
28 2.086243 server client TCP 6006 > 56150 [PSH, ACK] Seq=106 Ack=177 Win=50400 Len=21 "MSG_1 ECHO"
29 2.086440 client server TCP 56150 > 6006 [PSH, ACK] Seq=177 Ack=106 Win=66672 Len=22 "MSG_4 RCV"
30 2.086454 server client TCP 6006 > 56150 [ACK] Seq=127 Ack=199 Win=50400 Len=0
31 2.086659 server client TCP 6006 > 56150 [PSH, ACK] Seq=127 Ack=199 Win=50400 Len=21 "MSG_2 ECHO"
32 2.086708 client server TCP 56150 > 6006 [PSH, ACK] Seq=199 Ack=106 Win=66672 Len=22 "MSG_5 RCV"
33 2.086721 server client TCP 6006 > 56150 [ACK] Seq=148 Ack=221 Win=50400 Len=0
34 2.086947 server client TCP 6006 > 56150 [PSH, ACK] Seq=148 Ack=221 Win=50400 Len=21 "MSG_3 ECHO"
35 2.087196 server client TCP 6006 > 56150 [PSH, ACK] Seq=169 Ack=221 Win=50400 Len=21 "MSG_4 ECHO"
36 2.087500 server client TCP 6006 > 56150 [PSH, ACK] Seq=190 Ack=221 Win=50400 Len=21 "MSG_5 ECHO"
37 2.165390 client server TCP 56150 > 6006 [ACK] Seq=221 Ack=148 Win=66632 Len=0
38 2.166314 client server TCP 56150 > 6006 [ACK] Seq=221 Ack=190 Win=66588 Len=0
39 2.364135 client server TCP 56150 > 6006 [ACK] Seq=221 Ack=211 Win=66568 Len=0
REDHAT:
17 2.081163 client server TCP 55879 > 6006 [PSH, ACK] Seq=111 Ack=106 Win=66672 Len=22 "MSG_1 RCV"
18 2.081178 server client TCP 6006 > 55879 [ACK] Seq=106 Ack=133 Win=5888 Len=0
19 2.081297 server client TCP 6006 > 55879 [PSH, ACK] Seq=106 Ack=133 Win=5888 Len=21 "MSG_1 ECHO"
20 2.081711 client server TCP 55879 > 6006 [PSH, ACK] Seq=133 Ack=106 Win=66672 Len=22 "MSG_2 RCV"
21 2.081761 client server TCP 55879 > 6006 [PSH, ACK] Seq=155 Ack=106 Win=66672 Len=22 "MSG_3 RCV"
22 2.081846 server client TCP 6006 > 55879 [PSH, ACK] Seq=127 Ack=177 Win=5888 Len=21 "MSG_2 ECHO"
23 2.081995 server client TCP 6006 > 55879 [PSH, ACK] Seq=148 Ack=177 Win=5888 Len=21 "MSG_3 ECHO"
24 2.082011 client server TCP 55879 > 6006 [PSH, ACK] Seq=177 Ack=106 Win=66672 Len=22 "MSG_4 RCV"
25 2.082362 client server TCP 55879 > 6006 [PSH, ACK] Seq=199 Ack=106 Win=66672 Len=22 "MSG_5 RCV"
26 2.082377 server client TCP 6006 > 55879 [ACK] Seq=169 Ack=221 Win=5888 Len=0
27 2.171003 client server TCP 55879 > 6006 [ACK] Seq=221 Ack=148 Win=66632 Len=0
28 2.171019 server client TCP 6006 > 55879 [PSH, ACK] Seq=169 Ack=221 Win=5888 Len=42 "MSG_4 ECHO + MSG_5 ECHO"
29 2.257498 client server TCP 55879 > 6006 [ACK] Seq=221 Ack=211 Win=66568 Len=0
donc, J'ai eu confirmation que les choses ne fonctionnent pas correctement pour RH: le paquet 28 est envoyé TROP TARD, il ressemble le serveur attend l'ACK du paquet 27 avant de faire quoi que ce soit.
me semble que c'est la raison la plus probable ...
je réalise que les paramètres « Win » sont différents sur les haldes Solaris & RH: 50400 sur Solaris, seulement 5888 sur RH. c'est un autre indice ...
J'ai lu la doc sur la fenêtre coulissante & fenêtre tampon, et joué avec le rcvBuffer & sendBuffer en java sur mes prises, mais jamais réussi à changer cette valeur 5888 à toute autre chose (j'ai vérifié chaque fois directement avec tcpdump).
Est-ce que quelqu'un sait comment faire cela? J'ai du mal à obtenir des informations définitives, car dans certains cas il y a une "auto-négociation" que je pourrais avoir besoin de contourner, etc ...
J'ai finalement réussi à obtenir seulement partiellement débarrassé de mon problème initial en mettant le paramètre "tcp_slow_start_after_idle" à 0 sur RH, mais il n'a pas changé du tout le paramètre "win". le même problème était là pour les 4 premiers groupes de 5 messages, avec TCP retransmission & TCP Dup ACK dans tcpdump, alors le problème a disparu complètement pour tous les groupes suivants de 5 messages.
Cela ne me semble pas une solution très propre et/ou générique. J'aimerais vraiment reproduire exactement les mêmes conditions sous les deux systèmes d'exploitation.
Je continuerai à faire des recherches, mais toute aide des gourous TCP serait grandement appréciée!
La trace ne correspond pas à votre description. La trace redhat prend moins de temps que Solaris, donc je ne vois pas de problèmes de latence. Aussi l'écho est si rapide (moins de 1 ms) donc il semble que cela soit fait sur un loopback ou un LAN. –
timestamps sur le côté gauche ne peut pas être comparé (entre solaris & RH), ils sont simplement relatifs au moment où le premier paquet a été reçu (je pense) DANS CHAQUE BOÎTE, ce qui peut être à peu près n'importe quand. les tests ne sont pas effectués en même temps. le problème est le temps de réponse entre la réception de MSG et la réponse d'écho, mesurée sur le SERVEUR. sur solaris, tous les échos sont envoyés dans environ 2ms de la réception du premier msg (2.087500 - 2.085645 = 0.001855) sur RH, 4ème et 5ème échos sont envoyés 90ms plus tard (2.171019 - 2.081163) – Bastien