AWS SDK S3套接字已关闭异常

时间:2014-09-24 19:59:42

标签: java sockets amazon-web-services amazon-s3 aws-sdk

我的应用程序使用了近10个线程,每个线程每分钟可能会产生7,000个Put请求到S3。 (我在一个功能强大的EC2盒子上运行它可以很好地处理负载。)它可以运行近一个小时,但是,一小时后,得到Unable to execute HTTP request: Socket Closed例外:

        http.AmazonHttpClient: Unable to execute HTTP request: Socket Closed
    java.net.SocketException: Socket Closed
    at java.net.AbstractPlainSocketImpl.setOption(AbstractPlainSocketImpl.java:206)
    at java.net.Socket.setSoTimeout(Socket.java:1105)
    at sun.security.ssl.SSLSocketImpl.setSoTimeout(SSLSocketImpl.java:2414)
    at org.apache.http.impl.io.SocketInputBuffer.isDataAvailable(SocketInputBuffer.java:106)
    at org.apache.http.impl.AbstractHttpClientConnection.isResponseAvailable(AbstractHttpClientConnection.java:246)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.isResponseAvailable(ManagedClientConnectionImpl.java:180)
    at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
    at com.amazonaws.http.protocol.SdkHttpRequestExecutor.doSendRequest(SdkHttpRequestExecutor.java:47)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
    at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:713)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:518)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:446)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:256)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3641)
    at com.amazonaws.services.s3.AmazonS3Client.putObject(AmazonS3Client.java:1438)
    at com.amazonaws.services.s3.transfer.internal.UploadCallable.uploadInOneChunk(UploadCallable.java:128)
    at com.amazonaws.services.s3.transfer.internal.UploadCallable.call(UploadCallable.java:120)
    at com.amazonaws.services.s3.transfer.internal.UploadMonitor.upload(UploadMonitor.java:176)
    at com.amazonaws.services.s3.transfer.internal.UploadMonitor.call(UploadMonitor.java:134)
    at com.amazonaws.services.s3.transfer.internal.UploadMonitor.call(UploadMonitor.java:50)
    at java.util.concurrent.FutureTask.run(FutureTask.java:262)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

使用AWS SDK TransferManager异步完成Put请求。我想,在一个put请求完全完成所需的时间内,大约有10个是异步的。

谷歌搜索该异常,我发现了两个可能的原因:

  1. MaxConnections的限制。我把它从默认的50提高到3000,但没有用。
  2. 过早收集垃圾。我已经尝试保留对TransferManager返回的Upload对象的引用(在并发队列中),并且再一次没有帮助。
  3. 我该如何解决这个问题?再次,该应用程序运行良好近一个小时,但一直在大约一个小时后撞到这堵墙。 (我在EC2上的Amazon AMI Linux上运行。)

    更新

    • 除了AWS SDK之外,没有其他代码可以触及套接字,甚至不知道它们。所有HTTP工作都是通过AWS SDK完成的。
    • 因此,如果某些内容正在关闭,那么它必须是AWS SDK中的内容。
    • 代码在EC2服务器上运行;没有理由期望EC2和S3之间存在任何类型的网络连接问题,并且当然没有理由它们应该可预测地发生(每次运行一小时后)

4 个答案:

答案 0 :(得分:1)

我不确定这是否是答案,但是http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html声明"如果您预计存储桶的请求率快速增加到超过300 PUT /每秒LIST / DELETE请求或每秒超过800个GET请求,我们建议您打开支持案例以准备工作负载并避免对请求率的任何临时限制。也许自从我超出限制后,AWS开始中止连接; SDK,检测IDLE套接字,关闭它们,瞧!我们得到例外。

更新:不确定这是否正确。亚马逊似乎表示,在这种情况下,你会得到一个明确的"慢下来"错误消息,而不是意外关闭。所以,这个难题仍然存在。

答案 1 :(得分:1)

Exception是由java.net.Socket中的setSoTimeout()方法引起的SocketException(参见堆栈跟踪)。可以在此处查看该方法:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/net/Socket.java#Socket.setSoTimeout%28int%29

可能的原因可能是对S3的请求仍然未决/不完整导致线程等待()。等待时间超过套接字超时后,套接字将关闭并抛出异常。

答案 2 :(得分:-1)

我认为你最好试试ClientConfiguration.setSocketTimeout(int)。如果套接字是异步关闭的,我认为这是因为超时。根据亚马逊文件:

public void setSocketTimeout(int socketTimeout)

Sets the amount of time to wait (in milliseconds) for data to be transfered 
over an established, open connection before the connection times out and is closed. 
A value of 0 means infinity, and isn't recommended.

因此,根据该文档,如果连接超时,我认为它会自动关闭。

link:http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/ClientConfiguration.html#setSocketTimeout(int)

答案 3 :(得分:-3)

此例外只有一个原因。您或您的框架关闭了套接字,然后继续使用它。