我的应用程序使用近10个线程,每个线程每分钟可能会向S3发出大约7,000个Put请求。(我在一台性能强大的EC2机器上运行它,可以很好地处理负载。) 它运行得非常顺畅,接近一个小时,但是,一个小时后,出现“无法执行HTTP请求:套接字关闭”异常:
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个Put请求。
通过谷歌搜索该异常,我发现可能有两种原因:
- MaxConnections限制。我已将其从默认值50提高到3000,但无济于事。
- 过早进行垃圾回收。我尝试保留由TransferManager返回的Upload对象的引用(在并发队列中),但仍然没有帮助。
我该如何解决这个问题?再次强调,应用程序运行良好接近一个小时,但是,在一小时左右之后,始终会遇到这个问题。(我在EC2上运行Amazon AMI Linux。)
更新
- 除AWS SDK外,没有其他代码触摸套接字,甚至知道它们。所有HTTP工作都是通过AWS SDK独家完成的。
- 因此,如果有东西关闭它们,那一定是AWS SDK中的某些东西。
- 代码正在EC2服务器上运行;没有理由预期EC2和S3之间存在任何类型的网络连接问题,肯定没有理由预期它们会每次都可预测地出现(在运行一小时后)。
netstat -tn
的输出吗? - b4hand