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"); }); 

我发现当我在localhost / a上获取时,大约需要2.3秒才能完成。 这并不奇怪,因为它从数据库中获取了相当多的数据。 不过,我发现如果我/ B正在加载时,B不会显示。 就好像呼叫/ a阻止对/ b的呼叫一样。

这是expression如何工作? 我总是假设个别路由是asynchronous的,因为他们采取callback,但似乎是明文一次只能处理一个请求。 直到res.end()被调用,没有其他请求得到处理。 我是否缺less我需要的configuration?

作为参考,这是我如何连接到mongoose

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

编辑:这是卡模型和相关的模式+function的代码

 //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); } 

我一直在遇到同样的问题,有一个类似于你的设置。 有两个问题,它们都有相同的根本原因:节点具有非阻塞I / O操作,但是(如bbozo指出的),CPU密集型操作确实会阻塞它。

第一个问题在于你的mongoose电话。 mongoose从您的collections中检索文件后,将其转换为mongoose对象。 如果你得到了9000条logging,就会做9000次。 有问题的query.jsmongoose的query.js库; 检查它的completeMany函数上的for循环来查找相关的阻塞操作。

Express将string化生成的JSON对象发送您的响应时,会出现第二个问题。 罪魁祸首是Express的response.js库下的res.json函数。 对于一个大的反应, stringify的阻塞性质将是显而易见的。

我不太清楚如何解决这个问题。 你可以尝试使用mongodb的本地库,而不是mongoose。 您也可以尝试修补Express,以便使用JSONstream调用而不是阻塞string化。 分页查询和响应也将有所帮助,但我知道这不是很容易实现。

我会尽力 :)

Afaik Node.js在一般意义上并不是asynchronous的,从某种意义上讲它只是非阻塞的,如果一个连接什么也不做,那么另一个连接做什么事情不会被连接阻塞,

需要大量反应堆cpu时间的事情(如加载大量数据)将阻塞事件循环,尝试以较小的块读取数据

您可以设置精益选项。

启用精简选项的查询返回的文档是纯javascript对象,而不是MongooseDocuments。 他们没有保存方法,getters / setters或其他mongoose魔术应用。

例:

 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文档