Apache Camel:Aws-S3使用者在连接池超时时启动失败

时间:2015-08-21 08:47:09

标签: java amazon-s3 apache-camel

我正在使用AWS-S3使用者定期轮询S3上某个位置的文件。在轮询一定数量的时间之后,它开始失败,并给出了例外,

Will try again at next poll. Caused by:[com.amazonaws.AmazonClientException - Unable to execute HTTP request:
Timeout waiting for connection from pool]
com.amazonaws.AmazonClientException: Unable to execute HTTP request:Timeout waiting for connection from pool
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:376) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:202) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3037) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3008) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.services.s3.AmazonS3Client.listObjects(AmazonS3Client.java:531) ~[aws-java-sdk-1.5.5.jar:na]
at org.apache.camel.component.aws.s3.S3Consumer.poll(S3Consumer.java:69) ~[camel-aws-2.12.0.jar:2.12.0]
at org.apache.camel.impl.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:187) [camel-core-2.12.0.jar:2.12.0]
at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:114) [camel-core-2.12.0.jar:2.12.0]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_60]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) [na:1.7.0_60]

根据我的理解,原因是消费者耗尽了池中的可用连接,因为它在每次轮询时使用新连接。我需要知道的是如何在每次轮询后释放资源,以及为什么组件本身不会这样做。

骆驼版:2.12

编辑: 我修改了使用者以选择具有特定连接超时,maxconnections,maxerrorretry和sockettimeout的自定义S3客户端,但没有用。结果是一样的。

S3客户端配置:

ClientConfiguration clientConfiguration = new ClientConfiguration();
    clientConfiguration.setMaxConnections(50);
    clientConfiguration.setConnectionTimeout(6000);
    clientConfiguration.setMaxErrorRetry(3);
    clientConfiguration.setSocketTimeout(30000);
    main.bind("s3Client", new AmazonS3Client(awsCredentials, clientConfiguration));

名为“s3Client”的AmazonS3Client对象与Camel上下文绑定,并提供给基于Camel AWS-S3组件的路由。现在,Camel自己管理这个资源。

必需的解决方案:我期待解决方案特定于Camel Aws-S3使用者而不是通用Java解决方案,因为我知道在完成任务后它将被释放并再次使用。令人困惑的是,为什么Camel在提供连接池时没有自动执行此操作,或者我特别缺少任何配置。

2 个答案:

答案 0 :(得分:3)

Camel Consumer类为每个“Key”打开连接并创建一个交换。此交换转发到路由进行处理,但从不自动关闭,即使在呼叫“停止”时也是如此。结果是,连接池没有空闲连接。需要做的是从交换中提取S3ObjectInputStream并关闭它。

S3ObjectInputStream s3InputStream = exchange.getIn().getBody(S3ObjectInputStream.class);
s3InputStream.close();

答案非常接近其他人建议关闭连接的答案。但正如所解释的那样,Camel的具体答案是预期的,并解释了Camel为什么不自行处理这个问题。

答案 1 :(得分:1)

任何连接池概念都相同的地方。如果你无法获得连接,即使它是空闲的,在开发目的中我们需要通过检查连接是否空闲来显式调用close()。例如:

 if(con.isIdle()&& !con.closed()){
con.close();
}

然后,只有我们才能获得有关的信息。即使大多数框架都这样做,最好还是从我们的connectionFactory类中完成此代码。

编辑:

https://forums.aws.amazon.com/message.jspa?messageID=296676

此链接将帮助您获取特定答案,因为您没有指定S3Object连接类的代码。

编辑2:

在ClientConfiguration中尝试此方法

public ClientConfiguration withConnectionMaxIdleMillis(long connectionMaxIdleMillis)

这可能会解决您的错误,因为如果池中存在空闲连接且未重复使用,它会自动关闭连接。