Good day. I have a problem with the http client from apache. And so I have 2 servers that communicate with each other via REST. Let's call the one that receives requests (has an API) - the Server, and the one that sends - the Client. The server rotates on 8 volumes and API is implemented as @Controller from spring version 4.2.5. The client is spinning in jboss (4.2.3.GA) and is also based on spring 3.2.12. The client uses RestTemplate to call the API on the Server. Some API methods on the server run for quite a long time, 15-25 seconds. And sometimes when doing such methods I get the following error:

org.apache.http.NoHttpResponseException: The target server failed to respond at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:95) at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:62) 

however, in spite of the exception, the request from the Client reaches the Server and it is executed there for 15-20 seconds and then the exception is thrown. With requests that are executed for 1-2 seconds, such errors were not observed. ReadTimeout does not occur, yet the execution time of such methods is less.

Can you explain why an error occurs and how I can fix it?

Just in case, I will give the Client code:

 @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.setMessageConverters(ImmutableList.of(messageConverter)); restTemplate.setErrorHandler(errorHandler); HttpHost host = URIUtils.extractHost(new URI("http://127.0.0.1:8080")); HttpComponentsDigestRequestFactory requestFactory = new HttpComponentsDigestRequestFactory(host,new AuthProperties("user", "password", "realm")) requestFactory.setConnectTimeout(5000); requestFactory.setReadTimeout(30000); restTemplate.setRequestFactory(requestFactory); } 

 class HttpComponentsDigestRequestFactory extends HttpComponentsClientHttpRequestFactory { public HttpComponentsDigestRequestFactory(@NotNull HttpHost host, @NotNull AuthProperties auth) { DefaultHttpClient httpClient = (DefaultHttpClient) getHttpClient(); httpClient.getCredentialsProvider().setCredentials(new AuthScope(host, auth.getRealm(), "DIGEST"), new UsernamePasswordCredentials(auth.getUsername(), auth.getPassword())); } @Override protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri) { AuthCache authCache = new BasicAuthCache(); DigestScheme digestScheme = new DigestScheme(); digestScheme.overrideParamter("realm", realm); authCache.put(host, digestScheme); BasicHttpContext context = new BasicHttpContext(); context.setAttribute(ClientContext.AUTH_CACHE, authCache); return context; } 

 public void post(@NotNull String relativeUrl, @NotNull Object body, @NotNull Map<String, ?> uriVariables) { String url = gateway + relativeUrl; restTemplate.postForEntity(url, body, MyError.class, uriVariables); } private String json(Object body) { return gson.toJson(body); } 
  • Are you sure that the timeout is set when you are online? and that there are no afterPropertiesSet or anything like that? it is very likely that the value is not set for 30 seconds when you go online and remain default, but it falls out from time to time because of the data. those. once you have exceeded the timeout, another time there is less data - processing is faster - there is no timeout. - Victor
  • The default timeout is 60 seconds, I do 30. Even if the installation fails, it remains even longer. But I am sure that it is installed, because I tried to repeat the problem on my machine on the server in the Thread.sleep (30) method and then immediately crashed on the client with ReadTimeout, and if I did Thread.sleep (25), I did not crash . Could you explain in more detail because of what falls out? If I exceed the timeout then I have to be ReadTimeout, checked on several machines. And in that installation it gives out: The target server failed to respond. This is production, I can't experiment there - slippery

0