Quelle est la cause de prise ConnectException: Connection timed out?
Nous avons un Webstart client qui communique avec le serveur par l'envoi d'objets sérialisés sur HTTPS à l'aide java.net.HttpsURLConnection
.
Tout fonctionne parfaitement bien sur ma machine locale et sur les serveurs de test situé à notre bureau, mais je suis en train de vivre une très, très étrange question qui se produit uniquement sur notre production et la mise en scène des serveurs (et de façon sporadique). La principale différence que je sais d'entre ces derniers et ceux de notre bureau, c'est qu'ils se trouvent ailleurs et de la communication client-serveur avec eux est beaucoup plus lent, mais il a bien fonctionné pendant une longue période dans la production avant cette.
De toute façon, voici ce qui se passe:
- Le client, après réglage des options telles que le délai d'attente et des propriétés telles que
Content-Type
sur leHttpURLConnection
, les appelsgetOutputStream()
sur elle pour obtenir le flux d'écrire à. - À ce point, de ce que je peux dire, le client se bloque pendant une certaine période de temps.
- Le client puis lève l'exception suivante:
java.net.ConnectException: Connection timed out: connect à java.net.PlainSocketImpl.socketConnect(Native method) à java.net.PlainSocketImpl.doConnect(Source Inconnue) à java.net.PlainSocketImpl.connectToAddress(Source Inconnue) à java.net.PlainSocketImpl.connect(Source Inconnue) à java.net.SocksSocketImpl.connect(Source Inconnue) à java.net.Socket.connect(Source Inconnue) au com.soleil.net.le protocole ssl.interne.le protocole ssl.SSLSocketImpl.connect(Source Inconnue) au com.soleil.net.le protocole ssl.interne.le protocole ssl.BaseSSLSocketImpl.connect(Source Inconnue) au coucher du soleil.net.NetworkClient.doConnect(Source Inconnue) au coucher du soleil.net.www.http.HttpClient.openServer(Source Inconnue) au coucher du soleil.net.www.http.HttpClient.openServer(Source Inconnue) au coucher du soleil.net.www.le protocole.https.HttpsClient.(Source Inconnue) au coucher du soleil.net.www.le protocole.https.HttpsClient.Nouveau(Source Inconnue) au coucher du soleil.net.www.le protocole.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Source Inconnue) au coucher du soleil.net.www.le protocole.http.HttpURLConnection.plainConnect(Source Inconnue) au coucher du soleil.net.www.le protocole.https.AbstractDelegateHttpsURLConnection.connect(Source Inconnue) au coucher du soleil.net.www.le protocole.http.HttpURLConnection.getOutputStream(Source Inconnue) au coucher du soleil.net.www.le protocole.https.HttpsURLConnectionImpl.getOutputStream(Source Inconnue)
Noter que ce n'est pas un SocketTimeoutException
, qui le connect()
méthode sur HttpURLConnection
dit qu'il déclenche si le délai expire avant qu'une connexion puisse être établie. Aussi, quand cela arrive, je suis en mesure d'appeler conn.getResponseCode()
et je reçois un code de réponse de 200.
- Sur le côté serveur, un
EOFException
est jeté dansObjectInputStream
'constructeur, qui tente de lire la sérialisation d'en-tête mais ne parvient pas parce que le client n'est jamais leOutputStream
à écrire à.
Dans le cas où cela peut aider, voici les appels sur le HttpsURLConnection
avant l'appel de getOutputStream()
(modifiée pour afficher uniquement les appels faits plutôt que sur l'ensemble de la structure de la code de le faire):
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setReadTimeout(30000);
conn.setRequestProperty("Cookie", cookie);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/x-java-serialized-object");
conn.getOutputStream();
La chose est, je n'ai aucune idée de comment tout cela a pu être le cas, en particulier étant donné qu'elle n'arrive parfois (pas de tendance claire de l'activité que je peux dire) et même alors, seulement quand il y a (relativement) élevé de temps de latence entre le client et le serveur.
Étant donné ce que j'ai pu trouver jusqu'à présent sur java.net.ConnectException: Connect timed out
, je me demandais si ce n'était pas un réseau ou un problème de firewall sur le réseau de nos serveurs sont en cours d'exécution sur... mais cela ne fait pas beaucoup de sens pour moi étant donné que la demande est manifestement par le servlet. Aussi, d'autres applications fonctionnant sur le même réseau n'ont pas signalé des problèmes similaires.
Quelqu'un a une idée de ce que la cause de ce qui pourrait être, ou même ce que je dois étudier?
OriginalL'auteur ColinD | 2010-10-06
Vous devez vous connecter pour publier un commentaire.
Nous avons rencontré dans un cas similaire au vôtre. Habituellement, à forte charge et pas facile à reproduire sur le test. N'ont pas fixé encore mais c'est les étapes, nous sommes allés à travers.
Si c'est un problème de firewall, nous obtiendrions une Connexion Refusée ou le SocketTimeout exception.
1) Êtes-vous en mesure de suivre ces demandes dans le journal des accès sur le serveur - font-ils preuve d'un état HTTP 200 ou 404 ou autre chose? Dans notre cas, le serveur IIS (dans ce cas) les journaux ont montré que le client a fermé la connexion et non sur le serveur. C'était donc un mystère.
Mise à jour: Si le client obtient toujours un 200, puis le serveur a effectivement envoyé une réponse mais je soupçonne que la réponse de la taille en octets (si ce n'est enregistrée dans les journaux d'accès) affichera une valeur différente de celle de la réponse normale taille de la demande.
Si elle montre de la même taille de réponse, alors vous avez un (peut-être pas plausible) à condition que le serveur a vraiment répondu correctement mais le client n'a pas obtenu la réponse parce que la connexion résilié quelque part entre les deux.
2) L'administrateur réseau équipes se sont penchées sur le trafic TCP/IP pour déterminer l'extrémité (ou routeur intermédiaire) est appelé à disparaître HTTP /TCP-IP conversation. Et une fois que nous comprenons ce qui la fin est de mettre fin à la connexion est de chercher à comprendre pourquoi. Quelqu'un de bien informé assez peut exécuter snoop
3) Est-il un nombre maximum de demandes configuré/restreint sur le serveur et est-ce que la limitation de vos connexions?
4) il n'existe aucun intermédiaire des équilibreurs de charge au cours de laquelle les demandes ont pu être classées?
Mise à jour: encore Une chose que nous voulions, mais ne l'ont pas est de créer une route statique entre le client et le serveur afin de réduire le nombre de sauts entre les deux, et de s'assurer qu'aucun réseau en lien avec des gouttes. Voir http://en.wikipedia.org/wiki/Static_routing
5) une Autre suggestion est de définir la ConnectTimeout trop à voir si ces travaux avec une valeur plus élevée.
Mise à jour:, Vous pourriez vouloir essayer conn.getErrorStream()
6) Pourrait également essayer de prendre un ensemble de fil de vidage sur le serveur à 5 secondes d'intervalle, pour voir si un fil de discussion montre ces demandes entrantes sur le serveur.
Mise à jour:, dès aujourd'hui, nous avons appris à vivre avec ce problème, parce que nous avons totalisé le taux d'échec à 200-300 hors de 400 000 demandes par jour, ce qui est 0.00075 %
SocketTimeoutException
est levée lorsque cela est dépassé (plutôt que d'unConnectException
). Je ne suis pas sûr du tout de la les choses, mais tous semblent valoir la peine d'examiner.Ne conn.getErrorStream() comme dans ma mise à jour de montrer quelque chose d'intéressant?
Je n'ai pas eu la chance d'essayer encore, si, au vu de ce qui se passe du côté du serveur, il ne serait pas écrit quoi que ce soit à revenir vers le client.
J'ai fini par avoir à il suffit de mettre un lowish délai de connexion et d'appel
URLConnection.connect()
dans une telle manière que je peux réessayer de temps en temps si elle arrive à expiration. Pas l'idéal, mais nous n'avons pas été en mesure de déterminer exactement ce qui est à l'origine.OriginalL'auteur JoseK