情况是这样的:
http client ----> corporate firewall ----> http server
由于保持活动,服务器和客户端将保持 TCP 连接打开,客户端将使用连接池进行 HTTP 请求。
防火墙有一个规则,可以在 1 小时后“杀死”长期存在的 TCP 连接。问题是我们的 HTTP 客户端不会检测到 TCP 连接被破坏,它试图重用基本上死的连接,在我们这边看起来像客户端在一段时间后“挂起”。一个请求会挂起,然后下一个会工作,大概是因为建立了新的连接。
这里的问题是防火墙以我们的 HTTP 客户端无法检测到的方式杀死 TCP 连接的机制是什么。我尝试通过以下几种方式在本地重现此行为:
- 杀死我们 vyos 路由器上的 TCP 连接,客户端的 Wireshark 捕获 TCP FIN-ACK。行
- 在 Windows 上的 TCPView 中杀死 TCP 连接客户端,Wireshark 在客户端检测到 TCP RST。行
- 与客户端防火墙建立连接后阻塞端口,导致套接字重置异常。行
我在服务器端有一个 Wireshark 转储,我试图找出防火墙是否发送了 FIN 或 RST,ip.dst==serverip && (tcp.flags.reset==1 || tcp.flags.fin==1)
但没有显示任何内容。
此外,客户端的 Wireshark 捕获将问题显示为 HTTP 请求发出,然后是十多次 TCP 重传,最终无处可去。
HTTP 客户端是 Java 原生和/或 Jetty HTTP 客户端(都尝试过),两者都未能检测到死 TCP 连接。我想在本地重现该行为,但我无法弄清楚防火墙以何种狡猾的方式杀死连接,因此正在寻找可能的答案。