Java rest模板&x2B;ConnectionPoolTimeoutException:等待来自池的连接的超时

Java rest模板&x2B;ConnectionPoolTimeoutException:等待来自池的连接的超时,java,spring,apache-httpclient-4.x,resttemplate,Java,Spring,Apache Httpclient 4.x,Resttemplate,在应用程序没有任何负载的情况下,我在生产中突然出现了这个错误 当我的代码尝试使用SpringREST模板发送PUT消息时,出现了这个问题 下面是我初始化restTemplate的代码 private static final RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory()); { List<HttpMessageConverter<?>&

在应用程序没有任何负载的情况下,我在生产中突然出现了这个错误

当我的代码尝试使用SpringREST模板发送PUT消息时,出现了这个问题

下面是我初始化restTemplate的代码

private static final RestTemplate restTemplate = new RestTemplate(new HttpComponentsClientHttpRequestFactory());
{

    List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setClassesToBeBound(PaymentSession.class);
    MarshallingHttpMessageConverter marshallingHttpMessageConverter = new MarshallingHttpMessageConverter(marshaller, marshaller);
    marshallingHttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_XML, MediaType.TEXT_HTML));
    messageConverters.add(marshallingHttpMessageConverter);
    restTemplate.setMessageConverters(messageConverters);
}
原因:org.apache.http.conn.ConnectionPoolTimeoutException: 等待来自池的连接超时

这个错误是自我描述的。您需要在生产中增加连接池-当前实现的
HttpComponents客户端HttpRequestFactory
默认构造函数正在使用
HttpClientBuilder
.useSystemProperties()

我相信默认情况下会有5个连接。这适用于客户端,但不太可能是您在服务器环境中想要的。 你需要使用类似于

new RestTemplate(new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create()
                    .setMaxConnTotal(200)
                    .setMaxConnPerRoute(50)
                    .build()));

我建议将
HttpComponentsClientHttpRequestFactory
实例配置为在
RestTemplate
的构造函数中传递,增加
defaultMaxPerRoute
maxPerRoute
对于请求超时的特定http路由,增加池大小是不够的,正如我在一篇评论中提到的,即使将
poollighttpclientconnectionmanager.setMaxTotal()
设置为200,
HttpComponentsClientHttpRequestFactory
使用
defaultMaxPerRoute
值4,我猜可能是在尝试主机路由(方案、主机、端口)不劫持连接池)


我最近在博客上写了一篇关于使用
JMeter
和shell命令对超时请求进行故障排除的文章,并通过配置设置进行了修复。

问题在于HTTP客户端连接没有关闭。对于每秒只有1个请求的服务,我也遇到了同样的问题

"exception":"org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool"

您需要添加一个finally块并关闭连接。

我怀疑这是连接池大小的问题,因为我提到了这个问题是在非常低的负载下发生的,我们在对50个并发用户进行负载测试时没有遇到这个问题。但是,是的,我们将把池大小从5个增加到25个(4个服务器,即100个连接)@NullPointerException请同时设置超时值-可能是在连接失败的情况下需要几秒钟,因此它会退出池。@NullPointerException 30秒太高了-我可以想象,如果服务器位于地球的不同地区,则需要2-3秒。需要考虑的一点是,它不会无论池有多大,如果不设置.setMaxConnProute(),我认为默认情况下是4,它将只为同一主机使用4个连接,即使您可能还有196个连接处于空闲状态,我想这是为了防止主机劫持池。@BorisTreukhov不,这不是太高。有ConnectTimeout(建立连接需要多少时间)和ReadTimeout(请求完成需要多少时间)。如果我在拨号链接上读取10MB(仅举一个例子),那么30秒的ReadTimeout可能太低了。如果这是apache客户端的异常,并且我们使用的是RestTemplate包装器,怎么做?
new RestTemplate(new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create()
                    .setMaxConnTotal(200)
                    .setMaxConnPerRoute(50)
                    .build()));
...
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
        PoolingHttpClientConnectionManager result = new PoolingHttpClientConnectionManager();
        result.setMaxTotal(this.httpHostConfiguration.getMaxTotal());
        // Default max per route is used in case it's not set for a specific route
        result.setDefaultMaxPerRoute(this.httpHostConfiguration.getDefaultMaxPerRoute());
        // and / or
        if (CollectionUtils.isNotEmpty(this.httpHostConfiguration.getMaxPerRoutes())) {
            for (HttpHostConfiguration httpHostConfig : this.httpHostConfiguration.getMaxPerRoutes()) {
                HttpHost host = new HttpHost(httpHostConfig.getHost(), httpHostConfig.getPort(), httpHostConfig.getScheme());
                // Max per route for a specific host route
                result.setMaxPerRoute(new HttpRoute(host), httpHostConfig.getMaxPerRoute());
            }
        }
        return result;
    }
  ...


@Configuration
@ConfigurationProperties(prefix = "httpConnPool")
public class HttpHostsConfiguration {

  private Integer maxTotal;
  private Integer defaultMaxPerRoute;
  private List<HttpHostConfiguration> maxPerRoutes;

  // Getters, Setters
...
httpConnPool:
  maxTotal: 20
  defaultMaxPerRoute: 20
  maxPerRoutes:
    -
      scheme: http
      host: localhost
      port: 8800
      maxPerRoute: 20
"exception":"org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool"