2014-01-21 62 views
6

我有下面這段代碼ExpressJS - 如何處理同時發生的請求?請求似乎阻止彼此。

var express = require('express'); 
var routes = require('./routes');  
var http = require('http'); 
... 
app.get('/a',function(){ 
    Card.findCards(function(err, result){ //Mongoose schema 
    res.send(result); //Executes a query with 9000 records 
    }) 
}); 
app.get('/b', function(req, res){ 
    res.send("Hello World"); 
}); 

我發現,當我做一個GET在localhost /年,需要約2.3秒即可完成。這並不奇怪,因爲它從數據庫中獲取了相當多的數據。但是我發現如果我在/ a加載時GET/b,b將不會顯示。就好像呼叫/ a阻止對/ b的呼叫一樣。

這是表達應該如何工作?我總是假設個別路由是異步的,因爲它們接受回調,但看起來像express一次只能處理一個請求。在調用res.end()之前,不會處理其他任何請求。我是否缺少我需要做的配置?

僅供參考,我這是怎麼連接到貓鼬

mongoose.connect(dbConnectionString, {server:{poolSize:25}}); 

,這是我的http服務器初始化部分

http.globalAent.maxSockets = 20; // or whatever 

http.createServer(app).listen(app.get('port'), function(){ 
    console.log('Express server listening on port ' + app.get('port')); 
}); 

編輯:這裏是顯卡型號代碼和相關聯的模式+功能

//Card.js 
var mongoose = require('mongoose') 
    , Schema = mongoose.Schema; 

var CardSchema = new Schema({ 
    _id : {type: String}, 
    stores : [{ 
     store: {type: Schema.Types.ObjectId, ref:'StoreModel', required: true} 
     , points: {type: Number, required: true} 
    }] 
}); 

exports.findCards = function(callback){ 
    var query = Card.find({}, callback); 
} 

回答

0

我會試試:)

AFAIK的Node.js並非一般意義上的同步,它只是無阻塞在這個意義上,如果連接是什麼都不做那麼做了​​另一個連接不會被阻塞而什麼都不做連接,

需要大量反應堆cpu時間的事情(如加載大量數據)將阻止事件循環,嘗試以較小的塊獲取數據

+0

所以貓鼬分貝的呼叫阻塞?我一直認爲數據庫調用 - 就像輸入一樣 - 都是非阻塞的,因此使用了回調函數。 – pauloadaoag

+0

Moongoose數據庫調用是非阻塞的,因爲您的應用程序不會因爲等待mongo響應而被阻止,但是您的應用程序在從mongo到達時仍需要緩存和處理數千條記錄,並且佔用CPU週期反應堆 – bbozo

+0

這可能是真的,但我做了一個測試,其中我在消耗貓鼬電話的CPU之前調用了res.send(「hello world」)。即使用簡單的睡眠取代貓鼬呼叫,同樣的事情仍然發生。即使發生貓鼬呼叫,Express仍然處理請求。因此我的結論是,在任何給定的時間只有一個請求/響應對象可以被快速處理。 (函數(err,)函數,函數(){' 'console.log(「a」);' 'res.send(「a」);' 'Card.findCards(function(err,結果){' 'console.log(「done」);' '})' '});' – pauloadaoag

2

我一直在遇到同樣的問題,其設置類似於您的設置。有兩個問題,它們都具有相同的根本原因:節點具有非阻塞I/O操作,但是(如bbozo指出的),CPU密集型操作會阻止它。

第一個問題在於你的貓鼬叫。貓鼬從您的收藏中檢索文檔後,將其轉換爲貓鼬對象。如果您獲得9000條記錄,它將執行9000次。有問題的線路在貓鼬的query.js庫中;請檢查其completeMany函數的for循環以查找相關的阻止操作。

當Express將產生的JSON對象字符串化以發送您的響應時,第二個問題就出現了。罪魁禍首是Express的response.js庫下的res.json功能。對於一個大的迴應,stringify的阻塞性質將是顯而易見的。

我不太清楚如何解決這個問題。你可以嘗試使用mongodb的本地庫,而不是貓鼬。您也可以嘗試修補Express,以便使用JSON流調用而不是阻塞字符串化。分頁查詢和響應也會有所幫助,但我知道這不是很容易實現。

+0

我同意以上所述。 OP似乎做了正確的東西代碼明智的除了拉9k記錄然後序列化到JSON和發送9k記錄在電線上。無論你如何看待,它永遠不會擴展。分頁讓您始終可以控制您的響應時間。 – Biba

0

您可以設置精益選項。

啓用精簡選項的查詢返回的文檔是純javascript對象,而不是MongooseDocuments。他們沒有保存方法,getters/setters或其他貓鼬魔法。

例子:

new Query().lean() // true 
new Query().lean(true) 
new Query().lean(false) 

Model.find().lean().exec(function (err, docs) { 
    docs[0] instanceof mongoose.Document // false 
}); 

看到mongoose documentation