我的应用程序使用近 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)
使用 AWS 开发工具包 TransferManager 异步完成放置请求。我想,在一个 put 请求完全完成所需的时间内,大约有 10 个是异步的。
谷歌搜索该异常,我发现了两个可能的原因:
- MaxConnections 的限制。我已将其从默认的 50 提高到 3000,但无济于事。
- 过早的垃圾收集。我尝试保留对
Upload
TransferManager 返回的对象的引用(在并发队列中),但同样没有帮助。
我怎样才能解决这个问题?同样,该应用程序运行良好近一个小时,但始终如一地在大约一个小时后撞到这堵墙。(我在 EC2 上的 Amazon AMI Linux 上运行。)
更新
- 除了 AWS 开发工具包之外,没有任何代码接触到套接字,甚至不知道它们。所有 HTTP 工作都是通过 AWS SDK 专门完成的。
- 因此,如果有什么东西关闭了它们,那一定是 AWS 开发工具包中的东西。
- 代码在 EC2 服务器上运行;没有理由预计 EC2 和 S3 之间会出现任何类型的网络连接问题,当然也没有理由每次都应可预测地发生(运行一小时后)