我有以下代码
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秒才能完成。这并不奇怪,因为它从数据库中获取了相当多的数据。但是我发现如果在加载/ a时我得到GET / b,b将不会显示。好像对/ a的调用阻止了对/ b的调用。
这是表达应该如何工作吗?我一直在假设各个路由是异步的,因为它们接受回调但看起来像express一次只能处理一个请求。在调用res.end()之前,不会处理任何其他请求。我错过了我需要做的任何配置吗?
作为参考,这是我连接到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'));
});
编辑:以下是卡片模型和相关架构+功能的代码
//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 :(得分:2)
我遇到了同样的问题,设置类似于你的设置。有两个问题,它们都具有相同的根本原因:节点具有非阻塞I / O操作,但(如bbozo所指出的)CPU密集型操作会阻止它。
第一个问题在于你的猫鼬电话。在mongoose从您的集合中检索文档后,它会将它们转换为mongoose对象。如果您获得9000条记录,则会执行9000次。有问题的行是在mongoose的query.js
库中;检查其completeMany
函数的for循环,找到相关的阻塞操作。
当Express将生成的JSON对象字符串化以发送您的响应时,会出现第二个问题。罪魁祸首是Express res.json
库下的response.js
功能。对于较大的响应,stringify
的阻塞性质将会很明显。
我不太清楚如何解决这个问题。您可以尝试使用mongodb的本机库,而不是猫鼬。您也可以尝试修补Express,以便它使用JSON流调用而不是阻塞stringify。查询和响应的分页也会有所帮助,但我知道它的实现并不是很简单。
答案 1 :(得分:0)
我会尝试:)
Afaik Node.js在一般意义上不是异步的,它只是非阻塞,如果一个连接什么都不做,那么做某事的另一个连接不会被连接无效阻塞,
需要大量反应器CPU时间的事情(比如加载大量数据)会阻塞事件循环,尝试以较小的块获取数据
答案 2 :(得分:0)
您可以设置精益选项。
启用精益选项的查询返回的文档是纯JavaScript对象,而不是MongooseDocuments。他们没有使用保存方法,getter / setter或其他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
});