即使在配置组件选项后,Apache 骆驼连接池超时与 restlet
Apache camel Connection pool timeout with restlet even after configuring component options
我有一个调用 restlet 端点的 camel Java DSL 路由。当我手动点击相同的路线时,路线没有任何问题。但是,当我尝试通过代码发送大量请求时,我得到“超时等待来自池的连接”
下面是相同的stackt-race:
2016-01-29 14:09:38.650 WARN 20256 --- [pool-3-thread-2] org.restlet : An error occurred during the communication with the remote HTTP server.org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:412)
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getPoolEntry(ConnPoolByRoute.java:298)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.getConnection(ThreadSafeClientConnManager.java:238)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:423)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at org.restlet.ext.httpclient.internal.HttpMethodCall.sendRequest(HttpMethodCall.java:339)
at org.restlet.engine.adapter.ClientAdapter.commit(ClientAdapter.java:105)
at org.restlet.engine.adapter.HttpClientHelper.handle(HttpClientHelper.java:119)
at org.restlet.Client.handle(Client.java:153)
at org.restlet.Restlet.handle(Restlet.java:275)
at org.apache.camel.component.restlet.RestletProducer.process(RestletProducer.java:79)
at org.apache.camel.component.restlet.RestletProducer.process(RestletProducer.java:98)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:668)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:596)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:237)
at org.apache.camel.processor.Splitter.process(Splitter.java:104)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)
at org.apache.camel.processor.MulticastProcessor.doProcessParallel(MulticastProcessor.java:814)
at org.apache.camel.processor.MulticastProcessor.access0(MulticastProcessor.java:84)
at org.apache.camel.processor.MulticastProcessor.call(MulticastProcessor.java:314)
at org.apache.camel.processor.MulticastProcessor.call(MulticastProcessor.java:299)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
根据文档,我确实使用以下代码配置了 restlet 组件,但我仍然遇到同样的问题:
@Bean
public RestletComponent restlet()
{
RestletComponent restlet = new RestletComponent();
restlet.setMaxThreads(100);
restlet.setThreadMaxIdleTimeMs(10000);
restlet.setMaxQueued(20);
return restlet;
}
注意:路由确实一次接受了 10 个请求,然后我开始出错。从配置中我可以看到 maxThreads 默认为 10。这意味着我通过 Bean 所做的没有正确获取。
检查这些东西:
- 确保您已在 Spring 应用上下文 XML 文件中启用
<context:annotation-config/>
。
- 在SpringXML中使用
<context:component-scan base-package="<your package>" />
。
- 确保您已经用
@Configuration
. 注释了包含 @Bean
的内容
- 将
name
属性添加到 @Bean
:@Bean(name={"restlet"})
。
希望对您有所帮助。
实际上在我的代码中,我在路由配置后定义了 restlet bean,如下所示
public class RoutesBuilder extends FatJarRouter {
....
@Override
public void configure() throws JAXBException {
......
}
@Bean(name={"restlet"})
public RestletComponent restlet()
{
.......
}
}
现在我已经改变了定义代码的顺序,即首先我定义了 restlet 和路由配置如下。有了它,我看到 restlet 配置已被拾取,我不再看到连接池问题。
public class RoutesBuilder extends FatJarRouter {
....
@Bean(name={"restlet"})
public RestletComponent restlet()
{
.......
}
@Override
public void configure() throws JAXBException {
......
}
}
看看这个例子。它的Spring-启动APP。我创建了一个单独的配置 class 并使用了 spring-boot 配置注释,所以在启动时 spring-boot 会完成所有需要的配置
这是一个可行的解决方案
https://github.com/RakeshBhat/rb-springbootcamelrestlet
我有一个调用 restlet 端点的 camel Java DSL 路由。当我手动点击相同的路线时,路线没有任何问题。但是,当我尝试通过代码发送大量请求时,我得到“超时等待来自池的连接”
下面是相同的stackt-race:
2016-01-29 14:09:38.650 WARN 20256 --- [pool-3-thread-2] org.restlet : An error occurred during the communication with the remote HTTP server.org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:412)
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getPoolEntry(ConnPoolByRoute.java:298)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager.getConnection(ThreadSafeClientConnManager.java:238)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:423)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at org.restlet.ext.httpclient.internal.HttpMethodCall.sendRequest(HttpMethodCall.java:339)
at org.restlet.engine.adapter.ClientAdapter.commit(ClientAdapter.java:105)
at org.restlet.engine.adapter.HttpClientHelper.handle(HttpClientHelper.java:119)
at org.restlet.Client.handle(Client.java:153)
at org.restlet.Restlet.handle(Restlet.java:275)
at org.apache.camel.component.restlet.RestletProducer.process(RestletProducer.java:79)
at org.apache.camel.component.restlet.RestletProducer.process(RestletProducer.java:98)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:668)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:596)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:237)
at org.apache.camel.processor.Splitter.process(Splitter.java:104)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:141)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:460)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)
at org.apache.camel.processor.MulticastProcessor.doProcessParallel(MulticastProcessor.java:814)
at org.apache.camel.processor.MulticastProcessor.access0(MulticastProcessor.java:84)
at org.apache.camel.processor.MulticastProcessor.call(MulticastProcessor.java:314)
at org.apache.camel.processor.MulticastProcessor.call(MulticastProcessor.java:299)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
根据文档,我确实使用以下代码配置了 restlet 组件,但我仍然遇到同样的问题:
@Bean
public RestletComponent restlet()
{
RestletComponent restlet = new RestletComponent();
restlet.setMaxThreads(100);
restlet.setThreadMaxIdleTimeMs(10000);
restlet.setMaxQueued(20);
return restlet;
}
注意:路由确实一次接受了 10 个请求,然后我开始出错。从配置中我可以看到 maxThreads 默认为 10。这意味着我通过 Bean 所做的没有正确获取。
检查这些东西:
- 确保您已在 Spring 应用上下文 XML 文件中启用
<context:annotation-config/>
。 - 在SpringXML中使用
<context:component-scan base-package="<your package>" />
。 - 确保您已经用
@Configuration
. 注释了包含 - 将
name
属性添加到@Bean
:@Bean(name={"restlet"})
。
@Bean
的内容
希望对您有所帮助。
实际上在我的代码中,我在路由配置后定义了 restlet bean,如下所示
public class RoutesBuilder extends FatJarRouter {
....
@Override
public void configure() throws JAXBException {
......
}
@Bean(name={"restlet"})
public RestletComponent restlet()
{
.......
}
}
现在我已经改变了定义代码的顺序,即首先我定义了 restlet 和路由配置如下。有了它,我看到 restlet 配置已被拾取,我不再看到连接池问题。
public class RoutesBuilder extends FatJarRouter {
....
@Bean(name={"restlet"})
public RestletComponent restlet()
{
.......
}
@Override
public void configure() throws JAXBException {
......
}
}
看看这个例子。它的Spring-启动APP。我创建了一个单独的配置 class 并使用了 spring-boot 配置注释,所以在启动时 spring-boot 会完成所有需要的配置
这是一个可行的解决方案 https://github.com/RakeshBhat/rb-springbootcamelrestlet