我的应用程序使用将近 10 个线程,每个线程每分钟向 S3 发出大约 7,000 个 Put 请求。 (我在一个功能强大的 EC2 盒子上运行它,它可以很好地处理负载。)它完美地运行了将近一个小时,但是,一个小时后,得到 Unable to execute HTTP request: Socket Closed
异常(exception)情况:
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)
Put 请求是使用 AWS SDK TransferManager 异步完成的。我想,在一个放置请求完全完成所需的时间内,大约有 10 个是异步发出的。
谷歌搜索该异常,我发现了两个可能的原因:
- MaxConnections 的限制。我已将它从默认的 50 提高到 3000,但无济于事。
- 过早的垃圾收集。我尝试保留对 TransferManager 返回的
Upload
对象的引用(在并发队列中),但同样没有帮助。
我该如何解决这个问题?同样,该应用程序在将近一个小时内运行良好,但在大约一个小时后始终如一地撞墙。 (我在 EC2 上的 Amazon AMI Linux 上运行。)
更新
- 除了 AWS SDK 之外,没有任何代码接触到套接字,甚至不知道它们。所有 HTTP 工作都完全通过 AWS SDK 完成。
- 因此,如果有什么东西正在关闭它们,那一定是 AWS SDK 中的东西。
- 代码在 EC2 服务器上运行;没有理由预期 EC2 和 S3 之间会出现任何类型的网络连接问题,当然也没有理由每次都可以预见地发生(运行一个小时后)
最佳答案
我不确定这是否是答案,但是 http://docs.aws.amazon.com/AmazonS3/latest/dev/request-rate-perf-considerations.html声明 “如果您预计某个存储桶的请求率会快速增加到每秒超过 300 个 PUT/LIST/DELETE 请求或超过每秒 800 个 GET 请求,我们建议您打开支持案例以准备工作负载并避免对请求率的任何临时限制”。也许因为我超过了限制,AWS 开始中止连接; SDK,检测 IDLE 套接字,关闭它们,瞧!我们得到异常。
更新:不确定这是否正确。 Amazon 似乎声明,在这种情况下,您会收到明确的“Slow Down”错误消息,而不是意外关闭。所以,谜题仍然存在。
关于java - AWS SDK S3 套接字关闭异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26025444/