【问题标题】:Why is a http2 connection closed instantly compared to a http1 keep-alive connection?为什么与 http1 keep-alive 连接相比,http2 连接会立即关闭?
【发布时间】:2017-08-29 19:56:11
【问题描述】:

因为我们的浏览器游戏服务器在停机后很难为所有客户端提供服务(许多玩家刷新页面直到它再次工作)我正在尝试减少套接字连接。我们使用 nginx 1.10.3 为页面提供服务,并使用 http 1.1 keep-alive 连接。游戏的后端也使用 nginx 1.10.3 并使用 http 1.1 连接(没有保持活动状态!)。在这个设置过程中,我看到了很多处于TIME_WAIT 状态的 TCP 套接字,然后它们才最终关闭。这是正确的(见https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux)。

根据http://caniuse.com/#feat=http2,每个大型浏览器都支持http2,因此我尝试了一下。据我所知,http2 重用了 TCP 连接,因此它更快,因为当接收器已经有一个有效的 TCP 连接时,整个握手部分被跳过(一些其他特性使 http2 也更快)。

我使用netstat 监控所有活动的互联网连接,发现有时我的电脑和服务器只建立了一个连接。所有文件(jpg、css、html、js)都通过此连接传输。但有时我会看到两三个连接。这是否意味着 http2 可能会打开多个 TCP 连接,但它会尝试优化它们的重用?

我也等了几分钟,再次检查netstat,发现只有一个 TCP 连接处于打开状态(所有其他连接都已关闭)。我关闭了浏览器,刷新了netstat,然后 TCP 连接就消失了。但这应该是不可能的吧?连接/套接字应该仍然存在,但现在处于TIME_WAITFIN_WAITCLOSED 状态。还是 http2 允许/添加一个极快的套接字关闭机制?

【问题讨论】:

  • 谢谢,我为什么不自己想出这个...只是阅读它,但看起来并不是每个浏览器都像 RFC 想要的那样,对吧?例如,我使用 TCPView 检查打开了哪些套接字。我使用了 chrome 57 和 firefox 52。当我使用 chrome 并重新加载页面(CTRL + F5)时,套接字被重用。当我在 Firefox 中执行此操作时,套接字切换到 TIME_WAIT 状态并在一段时间后关闭。同时打开一个新的套接字并使用它。
  • Re “我关闭了浏览器,刷新了 netstat 并且 TCP-Connection 消失了。但这应该是不可能的,对吧?” - 肯定有可能。 AFAIK,它也是可能的,也是可取的。仅仅离开页面可以足以让浏览器说“我不再需要那个连接”[在链接的 RFC 中提到];关闭浏览器当然就是这样一个事件。

标签: sockets nginx tcp http2


【解决方案1】:

根据https://http2.github.io/http2-spec/

TCP 连接可以被任一对等方关闭。 END_STREAM 标志 在 DATA 帧上被视为等同于 TCP FIN 位。一种 客户端应发送设置了 END_STREAM 标志的 DATA 帧 在接收到带有 END_STREAM 标志的帧之后。一个代理 接收到设置了 END_STREAM 标志的 DATA 帧发送附加的 在最后一个 TCP 段上设置了 FIN 位的数据。一个代理 接收一个设置了 FIN 位的 TCP 段 发送一个 DATA 帧 END_STREAM 标志集。注意最后的 TCP 段或 DATA 帧 可能是空的。

另见5.1 Stream States。因此,基本上,不需要 TCP TIME_WAIT 状态,因为流的结束在更高的 OSI 级别上得到保证。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多