简体   繁体   English

NodeJS的高延迟

[英]High Latency with NodeJS

This problem pertains specifically to Nodejitsu, but similar effects seem to happen on other VPSes. 这个问题特别适用于Nodejitsu,但类似的效果似乎发生在其他VPS上。 I have a real time game using socket.io, and one thing I've noticed is that occasionally the server will wait an inordinate amount of time before responding. 我有一个使用socket.io的实时游戏,我注意到的一件事是偶尔服务器会在响应之前等待过多的时间。 If multiple requests are sent during that timeframe, they behave as if they've all been queued up and processed at once. 如果在该时间范围内发送了多个请求,则它们的行为就像它们已经排队并立即处理一样。 I suspect it's vaguely correlated to the presence of other users on the hardware shared (as is the case with any VPS). 我怀疑它与硬件共享上的其他用户的存在有着模糊的关联(就像任何VPS的情况一样)。

Anyway, to test this out (and make sure that it wasn't due to my game's code), I built a minimal test case: 无论如何,为了测试它(并确保它不是由于我的游戏代码),我构建了一个最小的测试用例:

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')
})

I had a simple blank HTML page with socket.io which would periodically send a perf event and time how long it took for the callback to fire. 我有一个简单的空白HTML页面,其中包含socket.io,它会定期发送一个perf事件,并计算回调触发所需的时间。 And it still shows the same thing: 它仍然显示相同的事情:

显示滞后峰值的图形

Note that the bar length represents the square root of the amount of time, not the linear quantity. 请注意,条形长度表示时间量的平方根,而不是线性数量。

When instead of relying on socket.io, I use XHR to do a similar measurement of the current response time, the result is pretty similar, a lot of low latency responses (though with a higher baseline than websockets, as expected) and some occasional spikes that appear to pile up. 当我不使用socket.io时,我使用XHR对当前响应时间进行类似的测量,结果非常相似,有很多低延迟响应(尽管基线比websockets高,如预期的那样),偶尔也有一些尖峰似乎堆积如山。

The odd thing is that if you open it up in multiple browser windows and different browsers, there seems to be a correlation between the different browsers (and the fact that it's totally absent or significantly less frequent on some servers) which seems to imply that it's a server side phenomenon. 奇怪的是,如果你在多个浏览器窗口和不同的浏览器中打开它,不同浏览器之间似乎存在相关性(并且它在某些服务器上完全不存在或频率显着降低)这似乎暗示它是服务器端现象。 However, there are latency spikes that happen for some browsers but not others, and the two Chrome windows which are of the same session appear to be virtually exact duplicates, which suggests that it's something that happens locally (per computer, or per browser, networking wise). 但是,某些浏览器会出现延迟峰值而其他浏览器不会出现延迟峰值,并且同一会话中的两个Chrome窗口看起来几乎完全相同,这表明它是本地发生的(每台计算机或每个浏览器,网络)明智的)。

From Left to Right: Chrome Incognito, Chrome (regular), Firefox, Chrome (regular) 从左到右:Chrome Incognito,Chrome(常规),Firefox,Chrome(常规)

四个窗口上的图表

Anyway, this has been confusing me for months and I'd really like to understand what is causing it and how to fix it. 无论如何,这让我困惑了几个月,我真的很想了解是什么导致它以及如何解决它。

I assume you checked if you have a cpu or ram issue. 我假设你检查过你是否有cpu或ram问题。

The only thing that can slow down node in a "surprising" way is the garbage collector - try to run your node with the --trace* to see what is going on. 唯一可以以“令人惊讶”的方式减慢节点的是垃圾收集器 - 尝试使用--trace*运行您的节点以查看正在发生的事情。 (See node --v8-options .) (参见node --v8-options 。)

I personally assue that you don't find out anything from that, because - and thats just my feeling - the issue is somewhere else. 我个人认为你没有发现任何东西,因为 - 这就是我的感觉 - 问题出在其他地方。

With that perfect delay of a multiply of 500ms I assume you have a packet loss. 有了500ms的乘法的完美延迟,我假设你有丢包。 You can check with ifconfig if that is a general issue and then tcpdump the packets and see if they retransmit. 如果这是一般性问题,您可以使用ifconfig进行检查,然后tcpdump数据包并查看它们是否重新传输。

I know this may sound strange but have you consider it is not an issue with node but with the OS setting. 我知道这可能听起来很奇怪,但你认为它不是节点的问题,而是OS设置。 Have you checked your file handles and the number of connections the OS is showing to the socket? 您是否检查了文件句柄以及操作系统向套接字显示的连接数? Have you also made sure the socket timeout in the OS is low enough? 您是否还确保操作系统中的套接字超时足够低? I have run into similar sounding performance issues with other code and it turned out to be the OS and not the code. 我遇到了与其他代码类似的声音性能问题,结果证明是操作系统,而不是代码。 Also check the package and see what it has for open allowed connections on the socket. 还要检查软件包,看看它对套接字上允许打开的连接有什么作用。 I ave not looked at the node code but ran into a similar issue with the http client library in java. 我没有查看节点代码,但遇到了与java中的http客户端库类似的问题。 The application just backed up and it was just a configuration issue with number of connections. 应用程序刚刚备份,这只是连接数量的配置问题。

The reason why you see this is because of Nagle's Algorithm. 你之所以看到这是因为Nagle的算法。 It's an algorithm used on I/O that buffers data for a while and then sends bigger chunks of data. 这是一种在I / O上使用的算法,它缓冲数据一段时间,然后发送更大的数据块。 It is used to save you transmissions (in sockets). 它用于保存传输(在套接字中)。 You can read more about it here http://en.wikipedia.org/wiki/Nagle's_algorithm 您可以在http://en.wikipedia.org/wiki/Nagle's_algorithm中阅读更多相关信息

To disable Nagle's algorithm (good when you want to send lots of small requests as fast as possible) you can do socket.setNoDelay(true); 要禁用Nagle的算法(当你想尽快发送大量小请求时很好)你可以做socket.setNoDelay(true); if you're using net.Socket() . 如果你正在使用net.Socket()。 In the case of socket.io I believe Nagle is already disabled by default for Websockets but not necessarily for other protocols. 在socket.io的情况下,我认为Nagle已默认为Websockets禁用,但不一定适用于其他协议。 I would recommend running a test with net.Sockets from node.js, disable Nagle and see what you get. 我建议使用来自node.js的net.Sockets运行测试,禁用Nagle并查看你得到的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM