2014-01-21 63 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