我的应用程序使用近10个线程,每个线程每分钟可能有7000个请求到S3. (我运行在一个强大的EC2盒子,可以处理负载相当不错).它运行很好,接近一个小时,但一个小时后,无法执行HTTP请求: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 SDK TransferManager异步完成的.我想象,在一个要求完全完成的时候,大约10个是异步的.
搜索这个例外,我发现了两个可能的原因:
> MaxConnections的限制.我把它从默认的50提高到了3000,没有效果.
>过早的垃圾收集.我尝试保留对TransferManager返回的上传对象的引用(在并发队列中),并且再次没有帮助.
如何解决这个问题?再次,应用程序运行良好接近一个小时,但一贯地,在大约一个小时后击中这堵墙. (我在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套接字,关闭它们,瞧,我们得到例外.
更新:不知道这是否正确.亚马逊似乎声明,在这种情况下,您会得到一个明确的“减速”错误消息,而不是意外关闭.所以,难题依然存在.