节点http服务器4 x保持活动禁用时更快?

时间:2016-03-06 21:19:23

标签: node.js http server keep-alive

Keep-alive应该可以加快网站的速度。

然而,当我在chrome(localhost:8080)中运行这个死的简单服务器时,我得到了这些加载时间:

    使用"连接:关闭" 标题(即取消注释setHeader行)

    100 ms

  • 400 ms左右启用标准keep-alive

我做错了什么?任何人都能重现我的结果吗?

过去两天我一直在敲打我的脑袋。

var fs = require('fs')
// preparing 50 2k files ...
var a = [], txt = '/*\n' + 'x'.repeat(2000) + '\n*/'
for (var i = 0; i < 50; i++) {
  var name = '/test' + i + '.js'
  fs.writeFile(__dirname + name, txt)
  a.push('<script src="' + name + '"></script>')
}
fs.writeFile(__dirname + '/index.html', a.join('\n') + '\nhello world')

var serve = function (req, res) {
  if (req.url === '/favicon.ico') {
    res.statusCode = 404; return res.end()
  }
  var pth = req.url + (req.url.match(/\/$/) ? 'index.html' : '')
  var s = fs.createReadStream(__dirname + pth)
  res.on('finish', function () { console.log('done', req.url) })
  // THIS IS THE KILLER LINE. Just uncomment and restart the server.
  // on my system, the page loads 4 times FASTER
  // res.setHeader('Connection', 'close')
  res.statusCode = 200; s.pipe(res)
}
require('http').createServer(serve).listen(8080)

修改

为清楚起见,使用标准快递服务器时的行为相同。以下服务器代码将产生相同的结果(至少在我的系统上)

// express server code
var express = require('express')
var app = express()
var closeConnection = function (req, res, next) {
  res.setHeader('Connection', 'close'); next()
}
// THIS IS THE KILLER LINE. Just uncomment and restart the server.
// on my system, the page loads 4 times FASTER
// app.use('*', closeConnection)
app.use(express.static(__dirname))
require('http').createServer(app).listen(8080)

2 个答案:

答案 0 :(得分:1)

这似乎归因于Nagle's algorithm active by default。这会导致在发送TCP数据包之前出现延迟,等待在一个数据包中发送可能更多的数据以避免过小的数据包。

由于关闭连接会导致立即发送待处理数据包,因此在不使用保持活动连接时不会影响延迟。

this answer中所述,Nagle的算法可以像这样禁用:

server.on("connection", function (socket) {
    socket.setNoDelay(true);
});

这应该可以解决延迟问题。请注意,如果您没有自己处理缓冲并发送大量小数据包,它可能会降低传输速率。

我注意到当响应被管道传输时出现问题(导致使用分块传输编码)(甚至使用Content-Length标头),但是在使用{{1}一次发送完整响应时却不会例如。

此外,从Node.js 8.0.0开始,这个问题似乎要少得多。在我的情况下,禁用Nagle算法仍会产生积极影响。

答案 1 :(得分:0)

服务器中发生的事情与互联网上发生的事情之间存在巨大差异,尽管我对您在此处报告的指标感到有些惊讶。您没有说明如何捕获指标或内容生成时间。我们可以假设后者不到100毫秒,这表明在你的loopback接口上发生了一些非常奇怪的事情,或者说node.js在这种情况下做了一些非常奇怪的事情,或者浏览器任务的调度可能阻止了webserver任务。

当然,如果要发布需要多个文件进行渲染的页面,并且正在通过互联网传递数据,禁用Keepalive应该会降低服务器负载和CPU使用率,但会增加页面加载时间。

我建议你开始添加其他组件,看看预期的状态何时恢复。我首先在一台单独的机器上运行客户端/运行多个客户端。