2014-01-21 9 views
6

私はローカルホスト/ Aに乗る作るとき、それが完了するまで約2.3秒かかることがわかりコード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/b中に/ aがロードされていれば、bは表示されません。これは/ aへの呼び出しが/ bへの呼び出しをブロックしているかのようです。

expressはどのように動作するはずですか?私は、コールバックを取るので個々のルートが非同期であることを前提にしていましたが、エクスプレスのように一度に1つのリクエストしか処理できないようです。 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')); 
}); 

EDITをマングースに接続する方法

です機能

//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

私は:)

を試してみましょうの

私の知る限りのNode.jsは、それは接続がその後、何かを別の接続が何もしない接続によってブロックされ得ることはありません何もしていない場合だけ意味での非ブロッキングだ、一般的な意味では、非同期ではありません

多くのデータをロードするなど、多くの原子炉のCPU時間がかかるものは、イベントループをブロックし、小さなチャンクでデータを取得しようとします。

+0

だから、マングースデシベルのコールがブロックされている

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

を参照してください?私はいつもdbコール(入力のような)は非ブロッキングでコールバックの使用を考えていました。 – pauloadaoag

+0

Moongoose db呼び出しは、あなたのアプリがmongoの応答を待つことによってブロックされないという意味で非ブロックですが、mongoから到着して数千のレコードをバッファして処理する必要があります。反応器 – bbozo

+0

それは本当かもしれませんが、私はCPUを消費する前にres.send( "hello world")と呼ばれるテストを行いました。 mongooseコールを単純な睡眠に置き換えても、同じことが起こった。 mongooseコールが行われている間でも依然として処理された要求を表示します。したがって、私の結論は、1つの要求/応答オブジェクトは、任意の時点で高速で処理できるということです。 ' 'console.log(" a ");' 'res.send(" a ");' 'Card.findCards(function(err、結果は) ' ' console.log( "done"); ' '}) ' '}) ' – pauloadaoag

2

私は同じ問題を経験しています。どちらも同じ根本原因を持つ2つの問題があります。ノードには非ブロックI/O操作がありますが、bbozoが指摘するように、CPUを大量に使用する操作はブロックします。

最初の問題は、あなたのマングースコールにあります。 mongooseはあなたのコレクションからドキュメントを取得した後、それらをmongooseオブジェクトに変換します。もしあなたが9000レコードを取得すれば、これは9000回になります。問題の行は、mongooseのquery.jsライブラリにあります。関連するブロック操作を見つけるために、そのcompleteMany関数のforループを調べてください。

Expressは、結果のJSONオブジェクトを文字列化してレスポンスを送信するときに発生します。原因は、Expressのresponse.jsライブラリのres.json機能です。応答が大きければ、ブロックする性質はstringifyです。

この問題を解決する方法がわかりません。おそらく、mongooseの代わりにmongodbのネイティブライブラリを使用しようとする可能性があります。また、Expressをパッチして、JSONストリームコールをブロッキングstringifyの代わりに使用するように修正することもできます。クエリとレスポンスのページネーションも役に立ちますが、実装するのはそれほど簡単ではないことがわかります。

+0

私は上記に同意します。 OPは、JSONにシリアライズして9kのレコードをワイヤに送り出すために9kのレコードをプルする以外は、適切なコードを賢明に実行するようです。それはあなたがそれをどのように見るかに関係なく、スケールアウトされません。あなたの応答時間を常にコントロールできるようにページネーションする。 – Biba

0

希薄オプションを設定できます。

リーンオプションが有効なクエリから返されるドキュメントは、MongooseDocumentsではなくプレーンなJavaScriptオブジェクトです。セーブメソッド、ゲッター/セッター、その他のマングースマジックは適用されません。

例:mongoose documentation

関連する問題