Skip to content

Instantly share code, notes, and snippets.

@rsedykh
Created November 11, 2020 21:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rsedykh/35289c07c11d9b55c9d008a7260eb0a6 to your computer and use it in GitHub Desktop.
Save rsedykh/35289c07c11d9b55c9d008a7260eb0a6 to your computer and use it in GitHub Desktop.
Zola reported remote_copy timeouts

Есть пользователь, у них часть запросов на копирование из Uploadcare в S3 (/files/remote_copy/) отваливвется по таймауту. Удалось выяснить, что их клиент не закрывал соединение, и они настроили закрытие сокета через 5 секунд, что помогло снизить кол-во проблемных запросов с 250/день до 4-8/день, но проблема все-же сохраняется. Они пробовали увеличить keep-alive до 6 секунд, но без успеха.

! Causing: javax.net.ssl.SSLException: Connection reset
! at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127)
! at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:326)
! at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:269)
! at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
! at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1576)
! at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:974)
! at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
! at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
! at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280)
! at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
! at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
! at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
! at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
! at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157)
! at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
! at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
! at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
! at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
! at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
! at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
! at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
! at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
! at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
! at com.uploadcare.api.RequestHelper.executeQuery(RequestHelper.java:159)
! ... 73 common frames omitted
! Suppressed: java.net.SocketException: Broken pipe (Write failed)
! at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
! at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
! at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
! at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
! at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:357)
! ... 95 common frames omitted
! Causing: com.uploadcare.exceptions.UploadcareNetworkException: Network failure!
! at com.uploadcare.api.RequestHelper.executeQuery(RequestHelper.java:169)
! at com.uploadcare.api.Client.copyFileRemoteStorage(Client.java:651)

Гипотеза от нашего девопса:

Моя гипотеза, что в клиенте на Java плохая конфигурация пула HTTP соединений: инициализируется пул, устанавливается соединение, производится запрос и обмен данными, соединение возвращается в пул до следующего запроса, через 630 секунд AWS ELB закрывает соединение, на клиенте соединение забирается из пула, отправляется запрос, всё сваливается с исключением из-за закрытого соединения. Введением таймаута в 6 секунд устранили эту ситуацию, но приобрели проблему раннего закрытия соединения. Нужен более глубокий анализ библиотеки.

Сейчас предложу клиенту увеличить таймаут до 30 секунд, чтобы он был эквивалентен нашему таймауту на бэкенде. Пока они наблюдают, изучу, может ли потенциально время обработки запроса на копирование упираться в наш таймаут — статистические выбросы в 15-20 секунд выглядят подозрительными.

Продолжение от нашего девопса:

Выяснил, операция копирования для клиента синхронная, таймаут 600 секунд. Если предложенное выше увеличение таймаута до 30 секунд существенно улучшит ситуацию (при условии, что больших файлов, на которые требуется более 30 секунд у клиента немного), нужно будет следующим этапом увеличить таймаут до 600 секунд, пока мейнтейнеры библиотеки Java не дадут свои рекомендации на сей счёт.

Технический бэкграунд для истории: запрос к API /files/remote_copy/ внутренне переадресуется к robots через accel redirect, где синхронно для клиента и выполняется копирование. Время копирования зависит от размера файла. Таймаут определяется таймаутом ELB и для api, и для robots.

Пользователю пока предложили увеличить лимит до 30 и понаблюдать.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment