问题: 我们已将 CDN 提供商设置为静态图像文件服务器的代理。几个小时后,我们发现 TCP SYN 丢失率极高,孤立连接数量异常高。
为了解决问题而采取的观察方法: 我捕获了 1.5 秒的服务器流量并检查了一些图像下载。可疑的是,nginx(几乎配置为默认设置)正在使用 ACK 而不是 FIN/ACK 响应 CDN 服务器的 FIN 数据包。在 nginx 发出 ACK 后,连接端口上整整一秒钟没有响应,这意味着服务器没有其他内容可发送。由于流量很大,我无法捕获超过 1.5 秒的数据。
以下是示例 TCP 连接的摘要:
No. Time Source Destination Proto Length and Info
20 0.004281671 [CDN IP] [NGINX IP] TCP 74 20200 → 443 [SYN] Seq=0 Win=28400 Len=0 MSS=1420 SACK_PERM=1 TSval=2822189024 TSecr=0 WS=1024
21 0.004333161 [NGINX IP] [CDN IP] TCP 74 443 → 20200 [SYN, ACK] Seq=0 Ack=1 Win=28960 Len=0 MSS=1460 SACK_PERM=1 TSval=2611883387 TSecr=2822189024 WS=128
372 0.125341624 [CDN IP] [NGINX IP] TCP 66 20200 → 443 [ACK] Seq=1 Ack=1 Win=28672 Len=0 TSval=2822189148 TSecr=2611883387
373 0.125357371 [CDN IP] [NGINX IP] TLSv1.2 287 Client Hello
374 0.125367976 [NGINX IP] [CDN IP] TCP 66 443 → 20200 [ACK] Seq=1 Ack=222 Win=30080 Len=0 TSval=2611883417 TSecr=2822189149
392 0.127328681 [NGINX IP] [CDN IP] TLSv1.2 2882 Server Hello, Certificate
393 0.127339623 [NGINX IP] [CDN IP] TLSv1.2 233 Server Key Exchange, Server Hello Done
645 0.244326565 [CDN IP] [NGINX IP] TCP 66 20200 → 443 [ACK] Seq=222 Ack=2984 Win=34816 Len=0 TSval=2822189267 TSecr=2611883418
646 0.244353033 [CDN IP] [NGINX IP] TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
647 0.244630520 [NGINX IP] [CDN IP] TLSv1.2 324 New Session Ticket, Change Cipher Spec, Encrypted Handshake Message
1121 0.360323576 [CDN IP] [NGINX IP] TLSv1.2 1496 Application Data
1122 0.360373767 [NGINX IP] [CDN IP] TCP 66 443 → 20200 [ACK] Seq=3242 Ack=1778 Win=33024 Len=0 TSval=2611883476 TSecr=2822189383
1123 0.360539425 [NGINX IP] [CDN IP] TLSv1.2 392 Application Data
1124 0.360614290 [NGINX IP] [CDN IP] TLSv1.2 97 Encrypted Alert
1554 0.477351117 [CDN IP] [NGINX IP] TCP 78 [TCP Window Update] 20200 → 443 [ACK] Seq=1778 Ack=3242 Win=40960 Len=0 TSval=2822189500 TSecr=2611883447 SLE=3568 SRE=3600
1555 0.477369934 [CDN IP] [NGINX IP] TCP 66 20200 → 443 [ACK] Seq=1778 Ack=3600 Win=43008 Len=0 TSval=2822189501 TSecr=2611883476
1596 0.505356016 [CDN IP] [NGINX IP] TCP 66 20200 → 443 [FIN, ACK] Seq=1778 Ack=3600 Win=43008 Len=0 TSval=2822189530 TSecr=2611883476
1597 0.505368886 [NGINX IP] [CDN IP] TCP 66 443 → 20200 [ACK] Seq=3600 Ack=1779 Win=33024 Len=0 TSval=2611883512 TSecr=2822189530
另外,我猜想 CDN 服务器使用 HTTP keep-alive 标头。我不确定的分析是 CDN 端的错误配置使其为每个图像使用一个连接并发送 keep-alive 标头。它使 nginx 让 TCP 保持活动状态,并且 FIN 数据包仅由 ACK 响应。然后一个解决方法是将 nginx keep-alive 超时减少到 1 秒。
问题:这个问题的具体原因是什么?或者我应该做哪些改变来解决这个问题?
答案1
是什么问题你想解决吗?
孤立连接和“SYN 丢失”其实不是问题。据我观察,NGINX 很少关心这些细节。
您添加了 CDN。并且该 CDN 不是用户. 因此它的行为有所不同。
您可能已经用完了池中的连接空间。请增加该空间。
请发布更具体的问题以获得更多清晰度。
答案2
我检查了请求的内容后发现,nginx 的行为是由于 CDN 的行为造成的。因为 CDN 使用的是保持活动连接,而 nginx 中保持活动连接的持续时间设置为 60 秒左右。当我将其减少到 15 秒时,情况恢复正常。