我在生产过程中突然出现了这个错误,而应用程序没有任何负载。
当我的代码尝试使用Spring rest模板
发送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);
}
致电PUT
try {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_XML);
HttpEntity<PaymentSession> httpEntity = new HttpEntity<PaymentSession>(session, headers);
restTemplate.exchange(baseUrl+"/v1/psps", HttpMethod.PUT, httpEntity, PaymentSession.class);
}catch(HttpClientErrorException e){
logger.error("Exception..!!",e)
}
异常堆栈跟踪
Caused by: org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
at org.apache.http.impl.conn.PoolingClientConnectionManager.leaseConnection(PoolingClientConnectionManager.java:232)
at org.apache.http.impl.conn.PoolingClientConnectionManager$1.getConnection(PoolingClientConnectionManager.java:199)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:88)
at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:46)
at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:49)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:509)
答案 0 :(得分:7)
引起:org.apache.http.conn.ConnectionPoolTimeoutException: 超时等待来自池的连接
此错误是自我描述的。您需要在生产中增加连接池 - HttpComponentsClientHttpRequestFactory
默认构造函数的当前实现使用HttpClientBuilder
和.useSystemProperties()
。
我相信默认情况下会有5个连接。这适用于客户端,但在服务器环境中不太可能。 你需要使用像
这样的东西new RestTemplate(new HttpComponentsClientHttpRequestFactory(HttpClientBuilder.create()
.setMaxConnTotal(200)
.setMaxConnPerRoute(50)
.build()));
答案 1 :(得分:7)
我建议配置Workbooks.Open Filename:="Workbook_FullName.xltm", Editable:=True
实例在HttpComponentsClientHttpRequestFactory
增加RestTemplate
或defaultMaxPerRoute
的构造函数中为请求超时的特定http路由传递,增加正如我在评论中提到的那样,游泳池大小还不够,即使您将maxPerRoute
设置为200,PoolingHttpClientConnectionManager.setMaxTotal()
使用的HttpComponentsClientHttpRequestFactory
为4,我的猜测也是为了尝试主机路由(方案,主机,端口)不要劫持连接池)
defaultMaxPerRoute
<强> application.yml 强>
...
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
...
我最近发表了关于Troubleshooting Spring's RestTemplate Requests Timeout的博客,其中使用httpConnPool:
maxTotal: 20
defaultMaxPerRoute: 20
maxPerRoutes:
-
scheme: http
host: localhost
port: 8800
maxPerRoute: 20
和shell命令并通过配置设置修复了请求超时的问题。
答案 2 :(得分:0)
问题是HTTP客户端连接没有关闭。我对每秒只有1个请求的服务有同样的问题。
"exception":"org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool"
您需要添加一个finally块并关闭连接。