私のアプリケーションは 10 近くのスレッドを使用しており、それぞれが 1 分あたりおそらく 7,000 の Put リクエストを S3 に送信します。(負荷をうまく処理できる強力な EC2 ボックスで実行しています。) 1 時間近くは問題なく動作しますが、1 時間後に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 SDK TransferManager を使用して非同期で行われます。1 つの put リクエストが完全に完了するまでに、約 10 件の put リクエストが非同期で行われたと思います。
その例外をグーグルで調べたところ、考えられる原因が2つ見つかりました。
- MaxConnections の制限。デフォルトの 50 から 3000 に上げましたが、役に立ちませんでした。
- 時期尚早のガベージ コレクション。TransferManager によって返されたオブジェクトへの参照を (同時キューで) 保持しようとしましたが
Upload
、やはり助けにはなりません。
どうすればこれを修正できますか? 繰り返しになりますが、アプリは 1 時間近く正常に動作しますが、一貫して、約 1 時間後にこの壁にぶつかります。(EC2 上の Amazon AMI Linux で実行しています。)
アップデート
- AWS SDK 以外のコードは、ソケットに触れたり、ソケットについて認識したりすることさえありません。すべての HTTP 作業は、AWS SDK を介してのみ行われます。
- したがって、何かがそれらを閉じている場合、それは AWS SDK の何かである必要があります。
- コードは EC2 サーバーで実行されています。EC2 と S3 の間で何らかのネットワーク接続の問題が発生することを予期する理由はありません。