В моем приложении используется около 10 потоков, каждый из которых составляет 7000 запросов на отправку по S3 в минуту. (Я запускаю его на мощном блоке 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 SDK TransferManager. Я полагаю, что в то время, когда требуется, чтобы один запрос был полностью заполнен, около 10 были сделаны асинхронно.
Исходя из этого исключения, я нашел две возможные причины:
- Предел MaxConnections. Я поднял его по умолчанию от 50 до 3000, но безрезультатно.
- Преждевременный сбор мусора. Я попытался сохранить ссылку на объекты
Upload
, возвращаемые TransferManager (в параллельной очереди), и опять же никакой помощи.
Как я могу это исправить? Опять же, приложение работает хорошо около часа, но, последовательно, ударяет по этой стене примерно через час. (Я работаю на Amazon AMI Linux на EC2.)
Update
- Никакой код, отличный от SDK SDK, не касается сокетов или даже не знает о них. Вся работа HTTP выполняется исключительно через AWS SDK.
- Итак, если что-то закрывает их, это должно быть что-то в SDK AWS.
- Код работает на сервере EC2; нет никаких оснований ожидать каких-либо проблем с подключением к сети между EC2 и S3, и, конечно, нет причин, по которым они должны происходить предсказуемо (через час в перспективе) каждый раз