2016-05-05 52 views
0

我已經爲我正在開發的多人遊戲編寫了後端節點服務器,並且大部分時間每個請求都需要大約20-100ms才能解決。然而,有時候(也許50個請求中有1個)我會做同樣的請求,需要2000 + ms來解決。查詢時間貓鼬偶爾需要3-4秒

服務器完全寫在node.js中,託管在heroku上。我正在使用貓鼬來調用數據庫。

以下是日誌的屏幕截圖,在頂部可以看到查詢的功能。請求以19:03:03.68發送,響應以19:03:03.73發送出去,將所有數據結束保存在19:03:03.74。 Heroku將請求記錄爲58ms,這是期望的結果。

下面是問題發生的時間。您可以看到來自兩個獨立客戶端的多個請求(每個客戶端每秒發送約1個請求,這是正確的)。然而,請求建立起來並且在大約2000-5000ms之後,它們都會一個接一個地快速解決。我試着縮小了這個問題,但沒有多少運氣,但我相信這與我查詢數據庫時相關,因爲您可以看到多個請求進入,但直到2300ms之後,數據庫的第一個查詢才真正解決。據我所知,這些請求與在20-100毫秒內解析並完全隨機發生的請求相同。

Console Log

實際的代碼類似於此服務器上(簡化了這一問題的緣故):

console.log (「request received」); 
    Game.findOne({‘id’: gameID}, function(err, theGame){ 
     console.log("First Query"); 

我還開了蒙戈外殼數據庫來尋找查詢服用過多的時間量(> 2000毫秒),此代碼:

db.system.profile.find({millis: {$gt : 2000} }).sort({ ts: 1}); 

下面是稍微修改的結果,其中應包括相關的一切:

{ "op" : "update", "ns" : "theDb.players", "query" : 
    { "_id" : ObjectId("572b8eb242d70903005df0df") 
    }, "updateobj" : 
    { "$set" : 
    { "lastSeen" : ISODate("2016-05-05T18:19:30.761Z"), "timeElapsed" : 16 
    } 
}, "nscanned" : 1, "nscannedObjects" : 1, "nMatched" : 1, "nModified" : 1, "fastmod" : true, "keyUpdates" : 0, "writeConflicts" : 0, "numYield" : 0, "locks" : 
{ "Global" : 
    { "acquireCount": 
    { "r" : NumberLong(2), "w" : NumberLong(2) } 
    }, "MMAPV1Journal" : 
    { "acquireCount" : 
    { "w" : NumberLong(2) }, "acquireWaitCount" : 
    { "w" : NumberLong(1) }, "timeAcquiringMicros" : 
    { "w" : NumberLong(7294179) } 
    }, "Database" : 
    { "acquireCount" : 
    { "w" : NumberLong(2) } 
    }, "Collection" : 
    { "acquireCount" : 
    { "W" : NumberLong(1) } 
    }, "oplog" : 
    { "acquireCount" : 
    { "w" : NumberLong(1) } 
    } 
}, "milli" : 2298, "execStats" : {}, "ts" : ISODate("2016-05-05T18:19:33.060Z") 

第二個結果:

{ "op" : "update", "ns" : "theDb.connections", "query" : 
    { "_id" : ObjectId("572b8eaf42d70903005df0dd") 
    }, "updateobj" : 
    { "$set" : 
    { "internalCounter" : 3, "lastCount" : 3, "lastSeen" : ISODate("2016-05-05T18:19:30.761Z"), "playerID" : 128863276517, "sinceLast" : 0 
    } 
    }, "nscanned" : 1, "nscannedObjects" : 1, "nMatched" : 1, "nModified" : 1, "keyUpdates" : 0, "writeConflicts" : 0, "numYield" : 0, "locks" : 
    { "Global" : 
    { "acquireCount" : 
     { "r" : NumberLong(2), "w" : NumberLong(2) 
     } 
    }, "MMAPV1Journal" : 
    { "acquireCount" : 
    { "w" : NumberLong(2) }, "acquireWaitCount" : 
     { "w" : NumberLong(1) }, "timeAcquiringMicros" : 
     { "w" :NumberLong(7294149) } 
    }, "Database" : 
    { "acquireCount" : 
     { "w" : NumberLong(2) } 
    }, "Collection" : 
    { "acquireCount" : 
     { "W" : NumberLong(1) } 
    }, "oplog" : 
    { "acquireCount" : 
     { "w" : NumberLong(1) } 
    } 
    }, "millis" : 2299, "execStats" : {},"ts" : ISODate("2016-05-05T18:19:33.061Z") 

我真的需要確保的延遲提出任何要求不超過500毫秒,否則在遊戲本身很傷腦筋。對於可能造成這種情況的原因以及如何弄清楚,我真的很茫然。

我假設問題的原因是timeAcquiringMicros太長了。我不確定是什麼造成這種情況。

*請注意,客戶端正在請求數據只有標準的http請求,我目前沒有使用任何套接字。

回答

2

好吧,我終於解決了這個問題。問題實際上並沒有與我所做的任何事情聯繫在一起。我正在使用mlab提供的有關heroku的沙箱計劃,我的應用程序正在與其他人一起使用沙盒計劃競爭處理時間。他們的查詢減慢了數據庫的響應時間,導致了這些峯值。

解決方案:我不得不升級到他們的共享集羣計劃。由於升級我沒有任何查詢時間不規範。