Ответ с потоком иногда приводит к ошибке «Сброс соединения по одноранговой сети» - PullRequest
0 голосов
/ 29 июня 2018

В нашем приложении есть маршруты для потоковой передачи документов JSON. Вот пример:

/** GET api/1/tenant/(tenantId)/ads/ */
def getAllAdsByOwner(advertiserId: AdvertiserId): Route =
  get {
    httpRequiredSession { username =>
      getAllTenantAds(username, advertiserId) { (adSource: Source[AdView, Any]) =>
        complete(adSource)
      }
    }
  }

Большую часть времени он работает, как и ожидалось, но иногда, особенно при наличии множества одновременных запросов, сервер начинает сбрасывать соединение сразу после отправки заголовков. Я протестировал скрипт, который запрашивает этот маршрут с помощью curl в цикле и прерывает работу, если запрос не удался. Он работал около 2 минут до остановки. Трассировка при сбое запроса выглядит следующим образом:

<= Recv header, 17 bytes (0x11)
0000: HTTP/1.1 200 OK
<= Recv header, 54 bytes (0x36)
0000: Access-Control-Allow-Origin: https://<...>
<= Recv header, 135 bytes (0x87)
0000: Access-Control-Expose-Headers: Content-Type, Authorization, Refr
0040: esh-Token, Set-Authorization, Set-Refresh-Token, asset-content-l
0080: ength
<= Recv header, 40 bytes (0x28)
0000: Access-Control-Allow-Credentials: true
<= Recv header, 24 bytes (0x18)
0000: Content-Encoding: gzip
<= Recv header, 23 bytes (0x17)
0000: X-Frame-Options: DENY
<= Recv header, 33 bytes (0x21)
0000: X-Content-Type-Options: nosniff
<= Recv header, 26 bytes (0x1a)
0000: Content-Security-Policy: .
<= Recv header, 20 bytes (0x14)
0000: default-src 'self';.
<= Recv header, 63 bytes (0x3f)
0000: style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;.
<= Recv header, 59 bytes (0x3b)
0000: font-src 'self' 'unsafe-inline' https://fonts.gstatic.com;.
<= Recv header, 99 bytes (0x63)
0000: script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.google
0040: apis.com https://maps.gstatic.com;.
<= Recv header, 69 bytes (0x45)
0000: img-src 'self' data: https://*.googleapis.com https://*.gstatic.
0040: com;.
<= Recv header, 8 bytes (0x8)
0000:
<= Recv header, 26 bytes (0x1a)
0000: Server: akka-http/10.1.3
<= Recv header, 37 bytes (0x25)
0000: Date: Wed, 27 Jun 2018 15:20:24 GMT
<= Recv header, 28 bytes (0x1c)
0000: Transfer-Encoding: chunked
<= Recv header, 32 bytes (0x20)
0000: Content-Type: application/json
<= Recv header, 2 bytes (0x2)
0000:
== Info: Recv failure: Connection reset by peer
== Info: stopped the pause stream!
== Info: Closing connection 0
curl: (56) Recv failure: Connection reset by peer

Тот же запрос проверен в Wireshark:

снимок экрана

Чтение журналов не дало подсказки о вероятном источнике проблемы. Ответ зарегистрирован как успешный:

[27-06-2018 19:44:52.837][INFO] access: 'GET /api/1/tenant/ca764a91-8616-409c-8f08-c64a40d3fc07/ads' 200 596ms

Версии используемого программного обеспечения:

  • Scala: 2.11.11
  • Акка: 2,5,13
  • akka-http: 10.1.3

Конфигурация:

Я пытался увеличить akka.http.host-connection-pool.max-connections до 128, но это не помогло. Может быть, у кого-то есть идея, если это ошибка в akka-http или проблема конфигурации?

1 Ответ

0 голосов
/ 12 марта 2019

Если в открытом соединении нет ввода-вывода для времени простоя, Akka закроет соединение, которое часто появляется как ошибка «сброса соединения по одноранговой сети». Попробуйте увеличить значение akka.http.server.idle-timeout.

Поскольку ваше значение akka.http.server.request-timeout такое же, как akka.http.server.idle-timeout, это условие гонки, между которыми тайм-аут будет первым, когда нет ввода-вывода. Иногда вы увидите 503; в других случаях возникает ошибка сброса соединения.

...