簡體   English   中英

NodeJS的高延遲

[英]High Latency with NodeJS

這個問題特別適用於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 Incognito,Chrome(常規),Firefox,Chrome(常規)

四個窗口上的圖表

無論如何,這讓我困惑了幾個月,我真的很想了解是什么導致它以及如何解決它。

我假設你檢查過你是否有cpu或ram問題。

唯一可以以“令人驚訝”的方式減慢節點的是垃圾收集器 - 嘗試使用--trace*運行您的節點以查看正在發生的事情。 (參見node --v8-options 。)

我個人認為你沒有發現任何東西,因為 - 這就是我的感覺 - 問題出在其他地方。

有了500ms的乘法的完美延遲,我假設你有丟包。 如果這是一般性問題,您可以使用ifconfig進行檢查,然后tcpdump數據包並查看它們是否重新傳輸。

我知道這可能聽起來很奇怪,但你認為它不是節點的問題,而是OS設置。 您是否檢查了文件句柄以及操作系統向套接字顯示的連接數? 您是否還確保操作系統中的套接字超時足夠低? 我遇到了與其他代碼類似的聲音性能問題,結果證明是操作系統,而不是代碼。 還要檢查軟件包,看看它對套接字上允許打開的連接有什么作用。 我沒有查看節點代碼,但遇到了與java中的http客戶端庫類似的問題。 應用程序剛剛備份,這只是連接數量的配置問題。

你之所以看到這是因為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並查看你得到的內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM