首页 > 解决方案 > 尽管有 http-alive,但有多个 tcp 连接

问题描述

我不确定我是否正确理解http-keep-alive,在我看来,它应该重用 tcp 连接,而不是建立一个新的连接。但是,我发现了一些非常奇怪的东西,似乎很难预料http keep-alive的行为。


服务器:NodeJS & Express ^4.16.3 和我已经使用 Wireshark 分析结果


情况一:

for(let i =1; i<11; i++){
  app.use('/' + i, (req, res) => {
    res.header('cache-control', 'no-store');
    res.send('i');
  });
}

server.keepAliveTimeout = 50000;

setTimeout(() => {
    for (let i = 1; i < 11; i++) {
      fetch('' + i).then(data => console.log(data));
    }
  }, 10000);


情况2:

for(let i =1; i<11; i++){
  app.use('/' + i, (req, res) => {
    res.header('cache-control', 'no-store');
    // here I have added timeout!
    setTimeout(() => {
      res.send('i');
    }, 2000);
  });
}

在此处输入图像描述


所以我的问题是,http keep alive 到底是什么意思?为什么它会这样?如果它不会在情况2中使用相同的tcp连接,那么keep alive是什么意思?

感谢您的任何想法!

标签: javascriptnode.jshttptcpkeep-alive

解决方案


是的,HTTP Keep Alive 应该重用您与服务器的 TCP 连接。服务器将 Header 附加Connection: keep-alive到响应中,因此客户端保持连接处于活动状态。因此,在您的服务器响应之前,客户端不会保持连接活动。

因此,在您的第一个场景中,服务器在收到请求后立即回复标头。所以第二个响应(实际上可以重用,你很幸运,因为服务器在发送第二个请求之前响应了你的请求)重用了 TCP 连接。

但在第二种情况下,服务器等待 2 秒发送响应,所以客户端直到接下来的 2 秒才知道它应该是一个保持活动连接。但是所有其他请求都需要在此之前发送,因此默认情况下它将为每个 HTTP 请求创建一个新连接。

如果您需要连续调用 HTTP 接口,例如 req -> res -> req -> res,这可能会很有效,但如果您想从服务器获取独立的数据集合,这也可能效率低下。

如果您有任何疑问,请在客户端尝试此操作,

setTimeout(() => {
    fetch('' + i).then(data => console.log(data));

    setTimeout(function () {
        for (let i = 2; i < 11; i++) {
            fetch('' + i).then(data => console.log(data));
        }
    }, 5000)
}, 10000);

推荐阅读