首页 > 解决方案 > 使用流响应有时会导致“对等连接重置”错误

问题描述

在我们的应用程序中,我们有流式传输 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

使用的软件版本:

配置:

我尝试增加到akka.http.host-connection-pool.max-connections128,但它没有帮助。也许有人知道这是 akka-http 中的错误还是配置问题?

标签: scalahttpstreamakkaakka-http

解决方案


如果空闲超时的打开连接上没有 I/O,Akka 将关闭连接,这通常显示为“对等连接重置”错误。尝试增加 akka.http.server.idle-timeout 值。

因为您的 akka.http.server.request-timeout 值与 akka.http.server.idle-timeout 相同,所以这是一个竞争条件,在没有 I/O 时将首先发生超时。有时,您会看到 503;其他时候,您将遇到连接重置错误。


推荐阅读