添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a webservice which is accepting a POST method with XML. It is working fine then at some random occasion, it fails to communicate to the server throwing IOException with message The target server failed to respond . The subsequent calls work fine.

It happens mostly, when i make some calls and then leave my application idle for like 10-15 min. the first call which I make after that returns this error.

I tried couple of things ...

I setup the retry handler like

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);

but this retry never got called. (yes I am using right instanceof clause). While debugging this class never being called.

I even tried setting up HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false); but no use. Can someone suggest what I can do now?

IMPORTANT Besides figuring out why I am getting the exception, one of the important concerns I have is why isn't the retryhandler working here?

I don't think it is something with client code. May be destination server is too busy in handling responses? – kosa May 11, 2012 at 21:22 I tried fiddler to bombard the destination server but it worked fine. I even tried to execute the same steps to reproduce the error using fiddler, but no luck! – Em Ae May 11, 2012 at 21:29 What kind of web server is running the service, and during the 10-15 minute wait is the service getting other requests, or is the service idle? – Shawn May 11, 2012 at 21:40

Most likely persistent connections that are kept alive by the connection manager become stale. That is, the target server shuts down the connection on its end without HttpClient being able to react to that event, while the connection is being idle, thus rendering the connection half-closed or 'stale'. Usually this is not a problem. HttpClient employs several techniques to verify connection validity upon its lease from the pool. Even if the stale connection check is disabled and a stale connection is used to transmit a request message the request execution usually fails in the write operation with SocketException and gets automatically retried. However under some circumstances the write operation can terminate without an exception and the subsequent read operation returns -1 (end of stream). In this case HttpClient has no other choice but to assume the request succeeded but the server failed to respond most likely due to an unexpected error on the server side.

The simplest way to remedy the situation is to evict expired connections and connections that have been idle longer than, say, 1 minute from the pool after a period of inactivity. For details please see the 2.5. Connection eviction policy of the HttpClient 4.5 tutorial.

I'm using HTTTPClient 4.5.1 , here for two continuous retry server failed respond but third time succeed, so why does it not connect in first attempt even i kept time 1 minute as metioned. – Kundan Atre May 16, 2016 at 13:37 Some connections may have expiration time beyond which they should be considered no longer valid / re-usable. Idle connections are perfectly valid and re-usable but momentarily being unused. – ok2c May 24, 2017 at 7:05 It depends on many factors. It should be safe for safe and idempotent methods as long as the server conforms to the HTTP spec with regards to method safety and idempotency. – ok2c Aug 4, 2017 at 9:56 Using one minute timeout as recommended here was exactly the problem cause in my case: apache client talking to local jetty server. AFAIK by default, jetty closes connections after 30 seconds of inactivity. Setting connectionManager.setValidateAfterInactivity(500), i.e., half a second solved my problem. I guess, a few seconds would do equally well, but I don't care. – maaartinus Dec 16, 2018 at 17:55 We're getting this error, but: we can see the request gets to the server, but the client apparently doesn't get the response, since we get the NoHttpResponseException. If the connection was indeed stale, as you state, then how could the server get the request to begin with? Can anybody explain this scenario? Would cleaning up stale connections fix this? – Frans Dec 17, 2018 at 13:37 Given that the original question specifies a POST, is a retry handler the right approach here? – Brian Agnew Nov 28, 2017 at 15:46 Are you asking if a POST is safe to retry? As a design principle, a PUT is idempotent. Retrying a POST may have unintended consequences. Then again, not all PUTs are written idempotently. – activedecay Apr 6, 2018 at 21:46 It is almost perfectly safe to retry POST request with the method I provided - because it handles and retries only NoHttpResponseException which is much more possisible due to client side rather then server side. – Jehy Apr 8, 2018 at 5:12 @Jehy It's not perfectly safe at all... NoHttpResponseException means that the client didn't get a response, not that the server didn't get and/or processed the request – Lyrkan Dec 6, 2018 at 9:27 the safety could be ensured by implementation, if content parts are re-used during key/identity creation, server could spit out 400 recognizing that the entry was already created. – Aubergine Feb 11, 2020 at 15:18

Solution: change the ReuseStrategy to never

Since this problem is very complex and there are so many different factors which can fail I was happy to find this solution in another post: How to solve org.apache.http.NoHttpResponseException

Never reuse connections: configure in org.apache.http.impl.client.AbstractHttpClient:

httpClient.setReuseStrategy(new NoConnectionReuseStrategy());

The same can be configured on a org.apache.http.impl.client.HttpClientBuilder builder:

builder.setConnectionReuseStrategy(new NoConnectionReuseStrategy());

HttpClient 4.4 suffered from a bug in this area relating to validating possibly stale connections before returning to the requestor. It didn't validate whether a connection was stale, and this then results in an immediate NoHttpResponseException.

This issue was resolved in HttpClient 4.4.1. See this JIRA and the release notes

I am using 4.5.3 version, but still getting NoHttpResponseException. In my case, I am getting this Exception in every 4th or 5th continuous request not in the 1st request. Any idea what might be the reason in my case? – Sahil Chhabra Feb 26, 2018 at 17:46

Although accepted answer is right, but IMHO is just a workaround.

To be clear: it's a perfectly normal situation that a persistent connection may become stale. But unfortunately it's very bad when the HTTP client library cannot handle it properly.

Since this faulty behavior in Apache HttpClient was not fixed for many years, I definitely would prefer to switch to a library that can easily recover from a stale connection problem, e.g. OkHttp.

  • OkHttp pools http connections by default.
  • It gracefully recovers from situations when http connection becomes stale and request cannot be retried due to being not idempotent (e.g. POST). I cannot say it about Apache HttpClient (mentioned NoHttpResponseException).
  • Supports HTTP/2.0 from early drafts and beta versions.
  • When I switched to OkHttp, my problems with NoHttpResponseException disappeared forever.

    Nowadays, most HTTP connections are considered persistent unless declared otherwise. However, to save server ressources the connection is rarely kept open forever, the default connection timeout for many servers is rather short, for example 5 seconds for the Apache httpd 2.2 and above.

    The org.apache.http.NoHttpResponseException error comes most likely from one persistent connection that was closed by the server.

    It's possible to set the maximum time to keep unused connections open in the Apache Http client pool, in milliseconds.

    With Spring Boot, one way to achieve this:

    public class RestTemplateCustomizers {
        static public class MaxConnectionTimeCustomizer implements RestTemplateCustomizer {
            @Override
            public void customize(RestTemplate restTemplate) {
                HttpClient httpClient = HttpClientBuilder
                    .create()
                    .setConnectionTimeToLive(1000, TimeUnit.MILLISECONDS)
                    .build();
                restTemplate.setRequestFactory(
                    new HttpComponentsClientHttpRequestFactory(httpClient));
    // In your service that uses a RestTemplate
    public MyRestService(RestTemplateBuilder builder ) {
        restTemplate = builder
             .customizers(new RestTemplateCustomizers.MaxConnectionTimeCustomizer())
             .build();
                    In my case, I am getting this Exception in every 4th or 5th continuous request not in the 1st request. Any idea what might be the reason in my case?
    – Sahil Chhabra
                    Feb 26, 2018 at 17:47
                    +1 Good, detailed answer, but... IMHO it's rather a workaround for the Apache HttpClient faulty behavior. The proper solution would be to switch to a library that is able to gracefully recover from a stale connection (e.g. OkHttp).
    – G. Demecki
                    Jun 3, 2019 at 9:30
                    you helped me a lot with your comment. I had the same issue as this but with Spring Cloud Zuul 1.3.2.RELEASE and under the high load  My solution was to copy-paste org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter and remove disableContentCompression call  I didn't change the dependency version because there is quite a mess with jars
    – Artem Ptushkin
                    Sep 5, 2019 at 15:30
                    :facepalm: that's incredibly bad idea. Persistent connections in HTTP world were introduced for some purpose. Abandoning them just because some client library is not able to use them properly is a huge mistake.
    – G. Demecki
                    Jun 3, 2019 at 9:38
    

    I have faced same issue, I resolved by adding "connection: close" as extention,

    Step 1: create a new class ConnectionCloseExtension

    import com.github.tomakehurst.wiremock.common.FileSource;
    import com.github.tomakehurst.wiremock.extension.Parameters;
    import com.github.tomakehurst.wiremock.extension.ResponseTransformer;
    import com.github.tomakehurst.wiremock.http.HttpHeader;
    import com.github.tomakehurst.wiremock.http.HttpHeaders;
    import com.github.tomakehurst.wiremock.http.Request;
    import com.github.tomakehurst.wiremock.http.Response;
    public class ConnectionCloseExtension extends ResponseTransformer {
      @Override
      public Response transform(Request request, Response response, FileSource files, Parameters parameters) {
        return Response.Builder
            .like(response)
            .headers(HttpHeaders.copyOf(response.getHeaders())
                .plus(new HttpHeader("Connection", "Close")))
            .build();
      @Override
      public String getName() {
        return "ConnectionCloseExtension";
    

    Step 2: set extension class in wireMockServer like below,

    final WireMockServer wireMockServer = new WireMockServer(options()
                    .extensions(ConnectionCloseExtension.class)
                    .port(httpPort));
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

    Camunda External client: TASK/CLIENT-02002 Exception while establishing connection for request See more linked questions