【问题标题】:Apache Camel: Aws-S3 consumer starts failing with connection pool timeoutApache Camel:Aws-S3 使用者因连接池超时而开始失败
【发布时间】:2015-11-15 03:34:12
【问题描述】:

我正在使用 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 在提供连接池时不会自动执行此操作,或者如果我特别缺少任何配置。

【问题讨论】:

    标签: java amazon-s3 apache-camel


    【解决方案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)
    

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

    【讨论】:

    • 我理解这一点,但在这种情况下您需要掌握连接实例。对于一个普通的 Java 请求,我当然会这样做,但在这种情况下,我正在寻找特定于 Camel AWS-S3 组件的东西。
    • 请提供您的S3Object代码及其实例?
    • 不幸的是,此方法不适用于我正在使用的版本。由于某些限制,我无法更新版本。
    【解决方案2】:

    Camel Consumer 类为每个“Key”打开连接并从中创建一个交换。此交换被转发到路由进行处理,但不会自动关闭,即使在调用“停止”时也是如此。结果,连接池耗尽了空闲连接。需要做的是将S3ObjectInputStream从exchange中提取出来并关闭。

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

    答案与其他人建议的关闭连接非常接近。但正如所解释的,Camel 具体的答案是意料之中的,并解释了为什么 Camel 不自己处理这个问题。

    【讨论】:

    • 您的回答不完整。你的路由定义是什么?你在哪里关闭流?
    • 能把骆驼相关代码的整个代码块贴在这里吗?
    猜你喜欢
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 2018-04-25
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多