【发布时间】:2014-11-19 10:49:32
【问题描述】:
我的应用程序使用近 10 个线程,每个线程每分钟向 S3 发出大约 7,000 个 Put 请求。 (我在一个功能强大的 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)
Put 请求使用 AWS 开发工具包 TransferManager 异步完成。我想,在一个 put 请求完全完成所需的时间内,大约有 10 个是异步发出的。
谷歌搜索该异常,我发现了两个可能的原因:
- MaxConnections 的限制。我已将其从默认的 50 提高到 3000,但无济于事。
- 过早的垃圾收集。我尝试保留对 TransferManager 返回的
Upload对象的引用(在并发队列中),但同样没有帮助。
我该如何解决这个问题?同样,该应用程序运行良好近一个小时,但始终如一地在大约一个小时后撞到这堵墙。 (我在 EC2 上的 Amazon AMI Linux 上运行。)
更新
- 除 AWS 开发工具包外,没有任何代码接触套接字,甚至不知道它们。所有 HTTP 工作都是通过 AWS SDK 专门完成的。
- 因此,如果有什么东西正在关闭它们,那一定是 AWS 开发工具包中的东西。
- 代码在 EC2 服务器上运行;没有理由预计 EC2 和 S3 之间会出现任何类型的网络连接问题,当然也没有理由每次都可预见地发生(运行一小时后)
【问题讨论】:
-
你能发布一些在不同数据集上重现问题的最小代码吗?发生这种情况时,您还可以显示您的
netstat -tn输出吗? -
@b4hand - 我会尽力搞定这一切。由于问题仅在大约 45 分钟后出现,因此实验速度很慢。这需要我一点时间,但我会努力的。
标签: java sockets amazon-web-services amazon-s3 aws-sdk