15

这个问题专门针对 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')
})

我有一个带有 socket.io 的简单空白 HTML 页面,它会定期发送一个perf事件以及回调触发所需的时间。它仍然显示相同的内容:

显示滞后峰值的图表

请注意,条形长度表示时间量的平方根,而不是线性量。

当我不依赖 socket.io 时,我使用 XHR 对当前响应时间进行类似的测量,结果非常相似,有很多低延迟响应(尽管基线比 websockets 高,正如预期的那样)和一些偶尔看起来堆积的尖峰。

奇怪的是,如果你在多个浏览器窗口和不同的浏览器中打开它,不同的浏览器之间似乎存在相关性(事实上它在某些服务器上完全不存在或频率显着降低),这似乎意味着它是服务器端现象。但是,某些浏览器会出现延迟峰值,而其他浏览器不会出现延迟峰值,并且同一会话的两个 Chrome 窗口似乎几乎完全相同,这表明这是本地发生的事情(每台计算机,或每台浏览器,网络明智的)。

从左到右:Chrome Incognito、Chrome(常规)、Firefox、Chrome(常规)

四个窗口上的图表

无论如何,这几个月来一直让我感到困惑,我真的很想了解导致它的原因以及如何解决它。

4

3 回答 3

2

我假设您检查了是否有 cpu 或 ram 问题。

唯一可以以“令人惊讶”的方式减慢节点速度的是垃圾收集器 - 尝试使用 运行您的节点--trace*以查看发生了什么。(见node --v8-options。)

我个人认为你不会从中找到任何东西,因为——这只是我的感觉——问题出在其他地方。

凭借 500 毫秒的完美延迟,我假设您有数据包丢失。您可以检查ifconfig这是否是一般问题,然后tcpdump检查数据包并查看它们是否重新传输。

于 2013-06-29T06:41:15.953 回答
0

我知道这听起来可能很奇怪,但您是否认为这不是节点的问题,而是操作系统设置的问题。你检查过你的文件句柄和操作系统显示到套接字的连接数吗?您是否还确保操作系统中的套接字超时足够低?我在其他代码中遇到了类似的听起来性能问题,结果是操作系统而不是代码。还要检查包,看看它在套接字上打开允许的连接有什么。我没有查看节点代码,但遇到了与 java 中的 http 客户端库类似的问题。应用程序刚刚备份,这只是连接数的配置问题。

于 2013-06-27T14:39:29.090 回答
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 并看看你得到了什么。

于 2013-06-29T15:47:37.797 回答