首页 > 解决方案 > Spring boot RestTemplate 关闭连接以获取 NULL 响应导致 ConnectionPoolTimeoutExceptions

问题描述

我们有一个 spring boot 应用程序,它对一堆后端进行 RESTFul 调用,其中一个有时返回空响应,并且我们观察到在这些实例期间连接没有释放,因为 RestTemplate 类中的这段代码:

protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback,
            ResponseExtractor<T> responseExtractor) throws RestClientException {

        Assert.notNull(url, "'url' must not be null");
        Assert.notNull(method, "'method' must not be null");
        ClientHttpResponse response = null;
        try {
            ClientHttpRequest request = createRequest(url, method);
            if (requestCallback != null) {
                requestCallback.doWithRequest(request);
            }
            response = request.execute();
            handleResponse(url, method, response);
            if (responseExtractor != null) {
                return responseExtractor.extractData(response);
            }
            else {
                return null;
            }
        }
        catch (IOException ex) {
            String resource = url.toString();
            String query = url.getRawQuery();
            resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
            throw new ResourceAccessException("I/O error on " + method.name() +
                    " request for \"" + resource + "\": " + ex.getMessage(), ex);
        }
        finally {
            if (response != null) {
                response.close();
            }
        }
    }

有没有办法在响应为空或出错时释放连接或使用内容?

编辑添加导致错误的代码:

MyHttpClientClass{ 
private X getResponseBody(RestClient client, URI uri, HttpMethod method, HttpEntity<T> entity, Class<R> responseType, MyErrorHandler errorHandler) {        
  try 
   {            String host = this.getHost();                        
      ResponseEntity<X> resp = client.exchange(uri, method, entity, responseType);          
    return resp.getBody();      
    } catch (HttpServerErrorException | HttpClientErrorException e) 
{           handleHttpException(e, errorHandler);           
throw e;        
} catch (Exception e) {             
log(e);             
throw e;        }   }   }

-----------

Class1 implements Callable<T>
{ 
 @Override  public T doCall() throws Exception { 
try 
{   return this.getRestClient().exchange(this.getUri(),                      
    this.getHttpMethod(), this.getEntity(), getResponseType()).getBody();       } catch (HttpClientErrorException ex) {                         throw ex; } catch (HttpStatusCodeException ex) {                        if(this.isNeededRetry(ex)) {                throw ex;           }else {                 return generateErrorResponse(ex).getBody();     }                   } catch (RestClientException ex) {              throw ex;       } catch (Exception ex) {            throw ex; } } }

----------
MySpringApplicationClass{  
   public X get(String api, String params, Class<R> responseType, String path, List<String> pathVariables, MyErrorHandler errorHandler) 
{ 
    return getResponseBody(...);
}}

标签: springspring-boothttpconnectionspring-resttemplate

解决方案


推荐阅读