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