此问题特别适用于Nodejitsu,但类似的效果似乎发生在其他VPS上。我有一个使用socket.io的实时游戏,我注意到的一件事是偶尔服务器会在响应之前等待过多的时间。如果在该时间范围内发送了多个请求,则它们的行为就像它们已经排队并立即处理一样。我怀疑它与硬件共享上的其他用户的存在有着模糊的关联(就像任何VPS一样)。
无论如何,为了测试它(并确保它不是由于我的游戏代码),我构建了一个最小的测试用例:
express = require('express')
http = require('http')
app = express()
server = http.Server(app)
io = require('socket.io').listen(server)
io.sockets.on('connection', function(sock){
sock.on('perf', function(data, cb){
cb([Date.now()]); //respond with the current time
})
})
app.get('/', function(req, res){
res.header("Access-Control-Allow-Origin", "*")
res.header("Access-Control-Allow-Methods", "HEAD,GET,PUT,POST,DELETE")
res.header("Access-Control-Allow-Headers", "X-Requested-With")
res.end(JSON.stringify([Date.now().toString()])); //http equivalent of perf function
})
server.listen(process.env.PORT || 6655, function(){
console.log('listening now')
})
我有一个简单的空白HTML页面,其中包含socket.io,它会定期发送perf
事件,并计算回调触发所需的时间。它仍然显示同样的事情:
请注意,条形长度表示时间量的平方根,而不是线性数量。
当我没有依赖socket.io时,我使用XHR对当前响应时间进行类似的测量,结果非常相似,很多低延迟响应(尽管基线比websockets高,如预期的那样)还有一些偶然的尖峰似乎堆积起来。
奇怪的是,如果你在多个浏览器窗口和不同的浏览器中打开它,不同的浏览器之间似乎存在相关性(并且它在某些服务器上完全不存在或显着不那么频繁)这似乎是意味着它是服务器端的现象。但是,某些浏览器会出现延迟峰值而其他浏览器不会出现延迟峰值,并且同一会话中的两个Chrome窗口看起来几乎完全相同,这表明它是本地发生的(每台计算机或每个浏览器,网络)明智的)。
从左到右:Chrome隐身,Chrome(常规),Firefox,Chrome(常规)
无论如何,这让我困惑了几个月,我真的很想了解是什么导致它以及如何解决它。
答案 0 :(得分:1)
我假设你检查过你是否有cpu或ram问题。
唯一能够以“令人惊讶”的方式减慢节点的是垃圾收集器 - 尝试使用--trace*
运行您的节点以查看正在发生的事情。 (见node --v8-options
。)
我个人认为你没有从中找到任何东西,因为 - 这就是我的感觉 - 问题出在其他地方。
对于500ms的乘法的完美延迟,我假设你有丢包。如果这是一般性问题,您可以查看ifconfig
,然后查看tcpdump
数据包并查看是否重新传输。
答案 1 :(得分:0)
我知道这可能听起来很奇怪,但您认为这不是节点的问题,而是操作系统设置。您是否检查了文件句柄以及操作系统向套接字显示的连接数?您是否还确保操作系统中的套接字超时足够低?我遇到了与其他代码类似的声音性能问题,结果证明是操作系统,而不是代码。还要检查软件包,看看它对套接字上允许打开的连接有什么作用。我没有查看节点代码,但遇到了与java中的http客户端库类似的问题。应用程序刚刚备份,这只是连接数量的配置问题。
答案 2 :(得分:0)
你之所以看到这是因为Nagle的算法。这是一种在I / O上使用的算法,它缓冲数据一段时间,然后发送更大的数据块。它用于保存传输(在套接字中)。您可以在http://en.wikipedia.org/wiki/Nagle's_algorithm
了解更多相关信息要禁用Nagle的算法(当你想尽快发送大量小请求时很好)你可以做socket.setNoDelay(true);如果你正在使用net.Socket()。在socket.io的情况下,我认为Nagle已默认为Websockets禁用,但不一定适用于其他协议。我建议使用来自node.js的net.Sockets运行测试,禁用Nagle并查看你得到的内容。