(voir Cette question ServerFault )
J'ai un client Java qui utilise une prise pour ouvrir des connexions simultanées sur la même machine. Je suis témoin d'un phénomène où une demande est extrêmement rapide, mais les autres voient un délai de 100 à 3000 millisecondes. Inspection de paquets à l'aide de Wireshark affiche tous les paquets SYN au-delà de la première attente depuis longtemps avant de quitter le client. Je vois cela sur les clients Windows et Linux. Qu'est-ce qui peut causer cela? Cela se produit lorsque le client est une boîte Windows 2008 ou une boîte Linux. P>
code ci-joint: p>
11 Réponses :
On dirait que vous utilisez une seule connexion HTTP sous-jacente. Donc, d'autres demandes ne peuvent pas être faites avant d'appeler ou vous devez utiliser un pool de connexions HTTP. P> Fermer () code> sur le INPUTStream code> d'un httpurlconnection code>, i. e. avant de traiter la réponse. P>
J'ai essayé d'utiliser directement la prise et de sauter la mise en œuvre HTTP allouée, et je vois toujours un délai de 3 secondes.
Si l'une des machines est une boîte de fenêtre Windows, je jetterais un coup d'oeil aux connexions simultanées maximales sur les deux. Voir: http://www.speedguide.net/read_articles.php?id=1497 < / a> p>
Je pense que c'est une limite de niveau d'application dans certains cas, vous devrez donc suivre le guide pour les élever. P>
En outre, si c'est ce qui se passe, vous devriez voir quelque chose dans le journal des événements système sur la machine incriminée. P>
Rien dans le journal des événements système. La limite maximale des connexions simultanées n'est pas censée être pertinente pour Windows 2008, à ma compréhension. La limite par défaut est 10, je vois des problèmes sur 2-3 connexions simultanées.
J'ai vu un comportement similaire lorsque je recevais des délais d'attente DNS. Pour tester cela, vous pouvez utiliser l'adresse IP directement ou entrer l'adresse IP dans votre fichier d'hôtes. P>
J'utilise directement l'adresse IP.
définit socket.settcpnodelay (true) code> aide? P>
TCPNodelay s'applique uniquement à une seule connexion uniquement.
Client Java qui utilise httpurlConnection pour ouvrir des connexions simultanées sur la même machine. p>
la même machine? Quelle application les clients acceptent-ils? Si vous avez écrit ce programme par vous-même, vous devez peut-être que votre serveur puisse accepter vos clients. Peut-être que c'est juste une application écrite écrite mal (ou pas rapide). Le code serveur ressemble à ceci, je pense; p>
xxx pré> si ce résultat est mauvais, que vous savez où le problème est situé.
J'espère que cela vous aidera à vous rapprocher de la solution. P>
Question: H2>
Pour effectuer le test, utilisez-vous l'adresse IP que vous avez reçue à partir du serveur DHCP ou
127.0 .0.1 code> Si cela du serveur DHCP, tout se passe à travers le routeur / commutateur / ... de votre entreprise. Qui peut ralentir tout le processus. P>sinon: p>
- dans Windows Tout TCP-Traffic (localhost to localhost) sera redirigé dans la couche logicielle du système (pas la couche matérielle), c'est pourquoi vous ne pouvez pas voir TCP-Trafic avec Wireshark. Wireshark ne voit que le trafic qui transmet la couche matérielle. Li>
Linux: WireShark ne peut voir que le trafic à la couche matérielle. Linux ne redirige pas sur la couche logicielle. C'est aussi la raison pour laquelle
inettaddress.getlocalhost (). GetAddress () code>127.0.0.1 code> retourne. P> li>Ainsi, lorsque vous utilisez Windows, il est très normal que vous ne pouvez pas voir le paquet SYN, avec Wireshark. P> LI> ul>
martijn. p> blockQquote>
J'ai essayé plusieurs applications de serveur (serveur HTTP, telnet, ...), pas un que j'ai écrit moi-même. Tout problème du côté serveur n'explique toujours pas pourquoi le paquet Syn ne quitte pas le client.
Je ne me connecte pas au 127.0.0.1, mais à un autre ordinateur. J'utilise directement l'IP directement et je vois les paquets Syn dans Wireshark, ils sont juste 3000 millis en retard.
Étant donné que le problème n'est pas reproductible, sauf si vous effacez le cache ARP associé, à quoi ressemble toute la trace de paquets d'une perspective de synchronisation, à partir du moment où la demande ARP est émise jusqu'à la suite du délai de 3 secondes? P>
Que se passe-t-il si vous ouvrez des connexions à deux IP différents? Les premiers connexions aux deux réussiront-ils? Si tel est le cas, cela devrait exclure des problèmes de JVM ou de bibliothèque. P>
La première syn ne peut pas être envoyée tant que la réponse ARP n'arrive. Peut-être que la pile OS ou TCP utilise un délai d'attente au lieu d'un événement de filetage au-delà du premier qui tente d'ouvrir une connexion lorsque l'adresse MAC associée n'est pas connue. P>
Imaginez le scénario suivant: P>
GC n'a rien à voir avec cela - cela se produit dans le petit script de test que j'ai écrit dans le corps de la question. Rien, il ne pouvait causer un cycle de 3 secondes.
Les connexions simultanées à plusieurs hôtes réussissent.
Vous faites la bonne chose à réduire la taille de l'espace problématique. Sur la surface, il s'agit d'un problème impossible - quelque chose qui se déplace entre les piles IP, les langues et les machines, et pourtant n'est pas reproductible arbitrairement (par exemple, je ne peux pas reproduire à l'aide de votre code sur Windows ni Linux). P>
Quelques suggestions, passant du haut de la pile au fond: p>
code - vous dites que cela se produit sur .NET et Java. Y a-t-il des combinaisons de langue / compilateur pour lesquelles il ne se produit pas? J'ai utilisé votre client parler au programme Sockettest de Sourceforge et "NC" avec des résultats identiques - aucun retard. De même, JDK 1.5 VS 1.6 n'a fait aucune différence pour moi. P>
- Supposons que vous allongez la vitesse à laquelle le client envoie des demandes, dites-en une 500 ms. Le problème reproduit-il? p> li>
pile IP - Peut-être que quelque chose se bloque dans la pile sur la sortie. Je vois que vous avez exclu NAGLE, mais n'oubliez pas de trucs stupides comme des pare-feu / des tables IP. J'aurais du mal à croire que la pile TCP sur Win et Linux était celle-ci, mais vous ne savez jamais. P>
- La manipulation des interfaces de bouclage peut être faibly. Est-ce que reprovez-vous lorsque vous utilisez la vraie adresse IP de la machine? Qu'en est-il de l'autre côté du réseau (ou mieux, dos à dos avec un câble X-over à une autre machine)? p> li>
NIC - Si les paquets se rendent aux cartes, envisagez des caractéristiques des cartes (déchargement TCP ou autre «manipulation spéciale» ou bizarrerie des Nics eux-mêmes. Avez-vous les mêmes résultats avec d'autres marques de NIC? P> LI> ul>
Attendez, cela n'a pas reproduit sur votre machine, même après avoir nettoyé le cache arp ?! Ceci est intéressant alors, car nous avons vu le problème dans plusieurs ordinateurs / réseaux. Quelles sont vos versions OSES?
Correct. ARP ne fait aucune différence ... ce qui est bien sûr non surprenant sur un test de bouclage (mais même sur mon réseau local, il n'a aucun impact, ce qui me dit que ma source reçoit rapidement les réponses ARP). Utilisation de RedHAT 4 Mise à jour 4 et Windows XP Pro SP3. Si vous pouvez reproduire lorsque ARP est effacé, mais pas lorsqu'il est préchargé avec la cible Mac et IP, cela indique que les réponses d'ARP ne sont pas restituées assez rapidement?
Une vidange TCP montre que les premières demandes de connexion reçoivent une réponse ARP en moins de 1 milli. Je pense que nous sommes très proches de comprendre cela (voir le lien vers RFC 1122 J'ai ajouté), mais ce n'est toujours pas une histoire complète. Pourquoi seulement quand j'utilise du code multithreaded? Pourquoi cela ne se passe-t-il pas dans un seul test fileté? Le problème a été reproduit en utilisant Netcat, BTW.
Le fait que vous voyez cela sur plusieurs clients, avec différents systèmes d'exploitation, et avec différents environnements d'application sur (je suppose) le même système d'exploitation est une indication forte que c'est un problème avec le réseau ou le serveur, et non le client. Ceci est renforcé par votre commentaire qui éliminant le tableau ARP reproduit le problème. P>
Avez-vous peut-être deux machines sur l'interrupteur avec la même adresse MAC? (dont l'une est probablement un routeur qui bloque l'adresse MAC). P>
ou plus probable, si je me souviens de l'arp correctement, deux machines qui ont la même adresse IP codée. Lorsque le client envoie "Qui est IP 123.456.123.456", les deux répondront, mais un seul n'écoute qu'une seule fois. P>
Une autre possibilité (j'ai vu cela se produire dans un environnement d'entreprise) est un serveur Rogue DHCP, donnant à nouveau les mêmes adresses IP à deux machines. P>
Cela se produit sur plusieurs réseaux / ordinateurs. Essayez d'exécuter le script ci-dessus à la maison, je parie que vous rencontrerez ce problème vous-même (si vous effacez le cache ARP).
Donc, vous dites que c'est un problème général avec TCP / IP? Pas grand chose que vous pouvez faire à ce sujet.
Si vous allez effacer votre table ARP, alors oui, il faudra du temps pour reconstruire. Cependant, il devrait s'agir d'une question de quelques douzaines de millisecondes sur un segment de réseau local. Je ne sais pas pourquoi cela prend plus de temps pour vous, mais je regarderais la topologie du réseau.
Avez-vous essayé de voir quels appels système sont fabriqués en exécutant votre client avec Strace A >. p>
Cela m'a été très utile dans le passé, tout en déboguant des problèmes de mise en réseau mystérieux em>. p>
Je n'ai pas trouvé de vraie réponse de cette discussion. La meilleure théorie que j'ai proposée est: p>
J'ai essayé de modifier le délai d'attente dans Windows 7 mais n'a pas réussi. Si quelqu'un peut reproduire le problème et fournir une solution de contournement, je serai le plus utile. De plus, si quelqu'un a plus de détails sur pourquoi ce phénomène ne se produit qu'avec plusieurs threads, il serait intéressant d'entendre. P>
Je vais essayer d'accepter cette réponse car je ne pense pas que l'une des réponses fournissait une véritable explication (voir Cette discussion sur Meta ). p>
C'est fondamentalement la même réponse que j'ai fournie. Bonne chance!
Quel est le répertoire d'écoute sur le serveur? Quelle est la rapidité avec laquelle il accepte les connexions? Si l'arriéré se remplit, l'OS ignore les tentatives de connexion. 3 secondes plus tard, le client essaie de nouveau et obtient maintenant que l'arriéré a été effacé. P>
Vous pouvez montrer du code ou un exemple de travail minimal pour reproduire ce comportement. Peut-être que quelque chose ne va pas avec vos fils Java ...
Afficher le code! Vous avez probablement un attribut qui doit être défini.
Pouvez-vous ajouter la sortie du programme? PS: Vos informations d'utilisation ne sont pas logiques. Votre premier argument doit être un int.
Utilisation fixe. Voici un exemple de sortie de mon ordinateur. Les chiffres ont un sens - mais quand j'ai essayé cela de plusieurs ordinateurs au travail, j'ai reçu des chiffres de plus de 3000 millisecondes: invoquant invoqué 82 85 95 92 89
Est-ce simplement un segment de réseau très occupé (non commuté) au travail?
Mattw - L'interrupteur n'est pas chargé fortement.
Utilisez-vous le même JVM sur tous les postes de travail où vous testez votre programme? Qu'est-ce que JVM est-ce?
DERNIER SUN JVM. Le problème reproduit lorsque nous avons porté le testeur à .NET.
Cela me semble que vous devez tester si vous pouvez ouvrir plusieurs connexions parallèlement à la même combinaison serveur / port à l'aide d'hyperterminal / telnet. Ce n'est pas clair pour moi de ce qui a été écrit si cela a été fait. Vous constaterez peut-être que les retards 100-3000 sont de faire avec le temps (aléatoire) pris pour la machine virtuelle Java à la poubelle Récupérer les prises (je sais que vous renvoyez que ci-dessous, mais peut-être qu'ils ne font aucun type d'objet fait une différence), et que votre Network i> est d'une manière ou d'une autre ou une autre rachat à votre client Windows qu'il ne peut effectuer qu'une connexion à un port distant à la fois.
Reproduit en utilisant necat. Voir le lien vers RFC 1122.
J'ai eu des problèmes similaires, et ceux-ci n'ont eu lieu qu'en période de trafic élevé. Je suis venu remarquer que dans ces situations se sont produites dans les paquets TCP arrivent en panne. Par Fefault, le système ne réorganise pas les raisons de performance. Le système est retourné à la normale lorsque tout le cadre a été abandonné et que cela a entraîné un retard dans les connexions qui arrivaient. Mais je pense que ce n'est pas votre cas.