保持连接,HTTP1.1和TCP之间有什么区别?

3

与 Http keep alive 相关的有两个标头:

Connection: Keep-Alive
Keep-Alive: timeout=5, max=1000
  1. 哪一方发送HTTP1.1的“Keep-Alive: param”?
  2. 当客户端和服务器使用HTTP1.1时,客户端会发送TCP保持活动探测吗?
  3. 为了使用HTTP1.1保持活动,客户端必须设置Connection: Keep-AliveKeep-Alive: param吗?

我有以上问题是因为:

最近我在使用http客户端时遇到了一个问题。自上次客户端发送请求后的2个小时内,一旦客户端发送请求,就再也听不到来自服务器的响应。为了找到原因,我做了以下事情:

  1. 在客户端和服务器两侧运行tcpdump。
  2. 客户端发送一个请求(并接收响应)
  3. 等待2个小时
  4. 客户端发送另一个请求(但没有收到任何响应)<--这是问题所在。

在两个请求之间,两侧的pcap都没有显示任何人发送FIN。服务器也没有收到第二个请求。我认为HTTP1.1保持活动传输出现了问题。


客户端和服务器之间有任何防火墙吗? - Greg Cowell
@GregCowell 他们之间没有防火墙。只有当客户端在上次发送请求后2小时内再次发送请求时,才会无法接收响应。我会更新PO。 - Tiina
2个回答

0

有关问题1和3,请参见: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive

  • 双方都可以发送 Connection:Keep-alive 和 Keep-alive: ....
  • 这两个标头都必须生效
  • 连接仍然可能随时关闭

关于问题2,请参见:HTTP Keep Alive and TCP keep alive

  • Tcp keep alive与此无关

如果在客户端和服务器之间存在 NAT,那么2小时对于保持空闲连接的功能来说可能太长了,但是如果双方都没有看到 FIN,则说明有人没有按照规范处理事情。


0

经过一段时间的研究,得出以下结论:HTTP1.1头部中的Connection keepalive和Keepalive参数并不一定意味着双方都会为此做出响应。但是,双方确实需要发送/接收FIN;客户端应该能够在任何一方发送/接收FIN之前继续发送数据包。

因此,我最终通过显式发送FIN来解决了这个问题。当客户端在60秒内没有数据传输时,它通过发送FIN关闭连接。这应该在服务器端实现。例如,如果服务器在60秒内没有收到任何响应,则关闭连接,但我没有找到Webflux netty服务器的这种配置。

一个可行的代码如下:

HttpClient
    .create()
    .tcpConfiguration(client -> client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
            .option(ChannelOption.SO_KEEPALIVE, true)
            .option(EpollChannelOption.TCP_KEEPIDLE, 300)
            .option(EpollChannelOption.TCP_KEEPINTVL, 60)
            .option(EpollChannelOption.TCP_KEEPCNT, 8)
    )

代码无法运行:

webClient.post()
    .uri(uri)
    .accept(MediaType.APPLICATION_JSON)
    .header("Keep-Alive", "timeout=60, max=1000") 
    .header(HttpHeaders.CONNECTION, "Keep-Alive")

在TCP中添加传输控制是有效的,而HTTP头部则不然,尽管对于HTTP API用户来说,他们不应该考虑它下面的层次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接