web-dev-qa-db-fra.com

Où dois-je commencer à enquêter sur SocketTimeoutException: lecture expirée

De temps en temps, je vois le stacktrace suivant dans le journal dans lequel, HttpClient socket expire en essayant d'accéder à text/script le contenu d'un autre serveur. Ma question est de savoir quels paramètres de configuration dois-je vérifier pour mon application J2EE exécutée sur Weblogic, sous Linux? Je recherche spécifiquement les éléments suivants.

  • Paramètres de délai d'expiration JVM
  • HttpClient params
  • Paramètres de timeout Weblogic ou toute autre configuration comme le nombre de threads, etc.
  • Paramètres d'application J2EE comme la configuration de servlet, etc.
  • Ressources du système d'exploitation comme les threads, les gestionnaires de fichiers et les processeurs
  • Tout autre paramètre de configuration pouvant influencer la connexion de socket
  • Les vidages de fils seraient-ils utiles?

Voici mon code

HTTPResponse httpClientResponse;
//do some stuff
httpClientResponse.getStatusCode(); // this is where it fails

et c'est le stacktrace

Java.net.SocketTimeoutException: Read timed out
at jrockit.net.SocketNativeIO.readBytesPinned(Native Method)
at jrockit.net.SocketNativeIO.socketRead(SocketNativeIO.Java:32)
at Java.net.SocketInputStream.socketRead0(SocketInputStream.Java)
at Java.net.SocketInputStream.read(SocketInputStream.Java:129)
at HTTPClient.BufferedInputStream.fillBuff(BufferedInputStream.Java:206)
at HTTPClient.BufferedInputStream.read(BufferedInputStream.Java:126)
at HTTPClient.StreamDemultiplexor.read(StreamDemultiplexor.Java:356)
at HTTPClient.RespInputStream.read(RespInputStream.Java:147)
at HTTPClient.RespInputStream.read(RespInputStream.Java:108)
at HTTPClient.Response.readResponseHeaders(Response.Java:1123)
at HTTPClient.Response.getHeaders(Response.Java:846)
at HTTPClient.Response.getStatusCode(Response.Java:331)
at HTTPClient.RetryModule.responsePhase1Handler(RetryModule.Java:92)
at HTTPClient.HTTPResponse.handleResponseImpl(HTTPResponse.Java:872)
at HTTPClient.HTTPResponse.access$000(HTTPResponse.Java:62)
at HTTPClient.HTTPResponse$2.run(HTTPResponse.Java:839)
at HTTPClient.HTTPResponse$2.run(HTTPResponse.Java:837)
at
HTTPClient.HttpClientConfiguration.doAction(HttpClientConfiguration.Java:666)
at HTTPClient.HTTPResponse.handleResponse(HTTPResponse.Java:837)
at HTTPClient.HTTPResponse.getStatusCode(HTTPResponse.Java:242) 

Merci

Je mettrai à jour ma question avec les constatations ci-dessous.

  1. Aucun délai d'expiration explicite n'est défini sur HttpClient, ce qui signifie que le délai d'expiration de la session http du serveur peut prendre effet.
  2. SO_TIMEOUT pour HttpClient est 0, ce qui signifie qu'il doit attendre indéfiniment.
23
RHT

Piste 1

Selon les javadocs, Httpclient ne semble pas avoir de valeur par défaut du délai d'expiration du socket. Pour répondre à la question dans votre mise à jour - le délai d'expiration de la session ne sera pas en vigueur ici. La valeur par défaut de Weblogic est de 30 minutes pour l'expiration de la session.

Le serveur session timeout représente la durée pendant laquelle HttpSession sera conservé en mémoire si l'utilisateur n'a pas accédé au serveur.

Le délai d'expiration du socket est le temps nécessaire pour garder le socket du serveur ouvert pendant le transfert des données vers l'appelant. Cela peut même être dû au fait que le serveur est toujours en train de traiter et d'écrire des données, mais cela prend un peu de temps et le client vient juste de s'arrêter pour l'attendre.

Certains liens suggèrent que cette valeur par défaut est de 60 secondes, mais les javadocs ne disent rien, dans tous les cas, vous pouvez définir cette valeur sur quelque chose comme 120 secondes pour voir si cela aide

http://hc.Apache.org/httpclient-3.x/apidocs/org/Apache/commons/httpclient/params/HttpConnectionParams.html#setSoTimeout (int)

Ce dont vous avez besoin, c'est de chronométrer les délais d'attente - si c'est clair. Signification - Ces erreurs apparaissent-elles après 30 secondes, 60 secondes ou 5 minutes de la demande sortante?

Je voudrais changer le SO_Timeout et réessayer

Piste 2 - Paramètres OS

Il existe les paramètres BEA recommandés pour les valeurs NDD qui régissent la durée pendant laquelle les connexions entrantes sont maintenues ouvertes et le nombre de connexions en attente, etc. Sous Solaris, ils sont obtenus en exécutant

/usr/sbin/ndd -get /dev/tcp tcp_time_wait_interval 
/usr/sbin/ndd -get /dev/tcp tcp_conn_req_max_q 
/usr/sbin/ndd -get /dev/tcp tcp_conn_req_max_q0 
/usr/sbin/ndd -get /dev/tcp tcp_ip_abort_interval 
/usr/sbin/ndd -get /dev/tcp tcp_keepalive_interval 

Pouvez-vous vérifier les documents Oracle pour les commandes équivalentes sur Linux et les valeurs auxquelles ils doivent être définis. Sur Solaris, mon expérience est que les valeurs par défaut ne sont pas suffisantes et doivent être mises à niveau selon les recommandations BEA (Oracle)

Piste 3: journaux Weblogic/accès externe

Avez-vous activé les journaux d'accès HTTP sur le serveur? Ces demandes ayant échoué apparaissent-elles avec une taille d'octet de réponse ou affichent-elles une taille de réponse 0? Quel code d'erreur ou code d'état HTTP est renvoyé?

Ou peut-être que ces délais dépassés ne sont pas du tout enregistrés dans les journaux d'accès?

Ici, je suppose que le serveur externe sur lequel les délais d'attente se produisent est également Weblogic, sinon - cette question est adressée à l'équipe du serveur externe pour leur plate-forme équivalente.

** Autres **

Habituellement, les vidages de threads aident, mais les vidages de threads doivent être effectués sur le serveur qui a un problème de délai d'attente. Vous êtes le client et vous avez réussi à obtenir une connexion, après quoi elle expire lors de la lecture de la réponse. Le serveur externe est-il donc surchargé? Manque de fils? CPU haut? Trop de demandes simultanées?

15
JoseK

Un autre aspect qui n'a pas été abordé ici est le pare-feu.

J'ai constaté que SocketTimeoutExceptions peut souvent être lié à un port qui n'est pas ouvert pour la communication ou à un pare-feu bloquant la communication des machines sélectionnées uniquement.

Dans le cas où vous déboguez un problème, assurez-vous également de rechercher s'il y a un pare-feu entre les deux machines essayant de communiquer et s'il y en a un, assurez-vous que les ports sont disponibles pour la communication entre les deux.

Ce qui est intéressant à propos des problèmes liés au pare-feu, c'est qu'il ne vous permet pas de savoir si le serveur est en panne ou ne répond pas. Le comportement typique consiste à laisser le client attendre indéfiniment. Vous êtes donc toujours laissé dans le noir. Un tel telnet simple sur le port du serveur devrait montrer s'il est disponible/ouvert pour la communication.

J'espère que cela t'aides.

0
Kzvi

Vous devriez enquêter

(a) le délai de lecture par défaut ou explicite HttpClient, selon celui qui est utilisé;

(b) pourquoi le serveur ne répond pas dans ce délai, s'il est censé le faire (afficher les journaux du serveur),

(c) sinon pourquoi le délai est trop court. De nombreux délais d'attente sont définis trop courts, par ex. quelques secondes. Ils devraient être d'une fraction décente d'une minute, et si le temps de réponse attendu est plus long, doubler ou tripler le temps de réponse attendu.

0
user207421