Apache HttpClient Intermédiaire D'Erreur: NoHttpResponseException
J'ai un webservice qui est d'accepter un POSTE méthode XML. Il travaille très bien à un certain aléatoire occasion, il ne parvient pas à communiquer au serveur jeter IOException avec message The target server failed to respond
. Les appels suivants, beau travail.
Il arrive le plus souvent quand je fais des appels et ensuite laisser ma demande d'inactivité pendant 10-15 min. le premier appel que j'ai faites après que retourne cette erreur.
J'ai essayé quelques choses ...
J'ai installé la nouvelle tentative gestionnaire
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(IOException e, int retryCount, HttpContext httpCtx) {
if (retryCount >= 3){
Logger.warn(CALLER, "Maximum tries reached, exception would be thrown to outer block");
return false;
}
if (e instanceof org.apache.http.NoHttpResponseException){
Logger.warn(CALLER, "No response from server on "+retryCount+" call");
return true;
}
return false;
}
};
httpPost.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryHandler);
mais cette nouvelle tentative ne l'ai jamais appelé. (oui, je suis en utilisant la droite instanceof clause). Lors du débogage de cette classe ne jamais être appelé.
J'ai même essayé de configurer HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false);
mais pas d'utilisation. Quelqu'un peut-il suggérer ce que je peux faire maintenant?
IMPORTANT
En plus de comprendre pourquoi je suis l'exception, l'une des principales préoccupations que j'ai est pourquoi ce n'est pas le retryhandler de travail ici?
- Je ne pense pas que c'est quelque chose avec code client. Peut-être le serveur de destination est trop occupé dans le traitement des réponses?
- J'ai essayé de violon pour bombarder le serveur de destination, mais il a bien fonctionné. J'ai même essayé d'exécuter la même procédure pour reproduire l'erreur à l'aide de fiddler, mais pas de chance!
- Quel type de serveur web est en cours d'exécution du service, et pendant les 10-15 minutes d'attente est le service en demandant à d'autres requêtes, ou le service est-il inactif?
- Tomcat. Pas de son d'une maquette de service atm et ce n'est pas de recevoir quelque chose d'autre, mais à mes appels.
Vous devez vous connecter pour publier un commentaire.
Les plus susceptibles de connexions persistantes qui sont maintenus en vie par le gestionnaire de connexions de devenir obsolètes. Qui est, le serveur cible arrête la connexion sur sa fin sans HttpClient être en mesure de réagir à cet événement, alors que le lien est inactif, ce qui rend la connexion à moitié fermé ou périmés. Ce n'est généralement pas un problème. HttpClient emploie plusieurs techniques pour vérifier la validité des connexions lors de sa location à partir de la piscine. Même si la rassis vérification de la connexion est désactivée et un état de connexion est utilisé pour transmettre un message de demande l'exécution de la requête échoue généralement dans l'opération d'écriture avec l'exception socketexception et obtient automatiquement une nouvelle tentative. Toutefois, dans certaines circonstances, l'opération d'écriture peut résilier sans exception et l'opération de lecture ultérieure retourne -1 (fin du flux). Dans ce cas HttpClient a pas d'autre choix que d'assumer la demande a réussi, mais le serveur n'a pas pu répondre plus probable en raison d'une erreur inattendue sur le côté serveur.
La façon la plus simple pour remédier à la situation est d'expulser expiré connexions et connexions qui ont été ralenti plus que, disons, à 1 minute de la piscine après une période d'inactivité. Pour plus de détails, veuillez voir cette section de la HttpClient tutoriel.
NoHttpResponseException
de temps à autre, bien que la demande a bien fonctionné après 1 ou 2 tentatives. Est-il possible d'ignorer l'info typeNoHttpResponseException
à partir du journal depuis que le code fonctionne bien?connectionManager.setValidateAfterInactivity(500)
, c'est à dire, une demi-seconde résolu mon problème. Je suppose que, quelques secondes ferait tout aussi bien, mais je n'ai pas de soins.NoHttpResponseException
. Si la connexion est en effet obsolète, comme vous le dites, alors comment pourrait le serveur obtenir de la demande pour commencer? Quelqu'un peut-il expliquer ce scénario? Serait de nettoyage rassis connexions résoudre ce problème?Accepté réponse est juste mais manque de solution. Pour éviter cette erreur, vous pouvez ajouter setHttpRequestRetryHandler (ou setRetryHandler pour apache composants 4.4) pour votre client HTTP, comme dans cette réponse.
HttpClient 4.4 souffrait d'un bug dans ce domaine concernant la validation éventuellement obsolètes les connexions avant de retourner au demandeur. Il n'a pas valider si une connexion a été vicié, et cela se traduit alors par une immédiate
NoHttpResponseException
.Ce problème a été résolu dans HttpClient 4.4.1. Voir cette JIRA et la notes de version
De nos jours, la plupart des connexions HTTP sont considéré comme persistant, sauf déclaration contraire. Toutefois, pour gagner du serveur de ressources que la connexion est rarement gardé à jamais ouvert, la valeur par défaut délai d'expiration de connexion pour de nombreux serveurs est assez court, par exemple 5 secondes pour que le serveur Apache httpd 2.2 et au-dessus.
La
org.apache.http.NoHttpResponseException
erreur vient probablement de l'une connexion persistante qui a été fermée par le serveur.Il est possible de définir le temps maximum pour garder les connexions non utilisées ouvertes dans le client Http Apache piscine, en millisecondes.
Avec Spring Boot, une façon d'y parvenir:
Même problème pour moi sur http apache client 4.5.5
l'ajout par défaut de l'en-tête
Connection: close
résoudre le problème
Bien accepté réponse est juste, mais à mon humble avis est juste une solution de contournement.
Être clair: il est parfaitement normal qu'une connexion persistante peuvent devenir obsolètes. Mais malheureusement, c'est très mauvais quand le client HTTP de la bibliothèque ne peut pas le gérer correctement.
Depuis ce mauvais comportement dans Apache HttpClient n'a pas été fixé depuis de nombreuses années, j'ai vraiment préfèrent passer à une bibliothèque qui peut facilement récupérer à partir d'une rassis problème de connexion, par exemple OkHttp.
Pourquoi?
NoHttpResponseException
).Quand je suis passé à OkHttp, mes problèmes avec
NoHttpResponseException
disparu à jamais.Cela peut se produire si
disableContentCompression()
est situé sur une mise en commun gestionnaire attribué à votre HttpClient, et le serveur cible est d'essayer d'utiliser la compression gzip.