2012-08-03 13 views
32

これは私には少し不明な点です(私はNodeとMongoを使い始めています)。サーバのパフォーマンスと負荷のために本当に懸念されています(別の質問ですが、それはポストの終わりに)。Node.js上のMongoDB接続のベストプラクティスは何ですか?

a)のDB接続をオープンし、グローバルに保管し:私は、私は各APIエンドポイントが関数に対応するのNode.jsとRestify、とのAPIを書いていなければならないと仮定ので

、 varを使用して、それをすべての関数で使用しますか?
例:

// requires and so on leave me with a db var, assume {auto_reconnect: true} 
function openDB() { 
    db.open(function(err, db) { 
     // skip err handling and so on 
     return db; 
    } 
} 

var myOpenDB = openDB(); // use myOpenDB in every other function I have 

b)のDB接続を開き、ただ1つの巨大な閉鎖にすべてをかける
例:

// same as above 
db.open(function(err, db) { 
    // do everything else here, for example: 
    server.get('/api/dosomething', function doSomething(req, res, next) { // (server is an instance of a Restify server) 
     // use the db object here and so on 
    }); 
} 

C)オープンとDBにそれが必要とされるたびに閉じ?
例:

// again, same as above 
server.get('/api/something', function doSomething(req, res, next) { 
    db.open(function(err, db) { 
     // do something 
     db.close(); 
    }); 
}); 

server.post('/api/somethingelse', function doSomethingElse(req, res, next) { 
    db.open(function(err, db) { 
     // do something else 
     db.close(); 
    }); 
}); 

この最後のものは、私は直感の外に何をするのかであるが、同時に、私はこれをやって完全に快適に感じることはありません。 Mongoサーバーに負担をかけることはありませんか?特に(そして私がそれに到達することを願って)何百もの呼び出しではなく、何百もの呼び出しを得ます。

ありがとうございます。

+1

オプションBでは、名前付き関数を使用して大量のクロージャを回避できるので、コールバックhellを回避できます。つまり、ノードを使用しているなら、あなたはモジュールを使用しています(私は望みます)。(いくつかの少数の宣言された!)グローバル変数を持つことを意味します - 他の誰の名前空間も汚染しません。モジュールのエクスポートを除く '.js'ファイル – Gijs

+0

ありがとう!あなたはオプションBを使うことを提案しますか?私はドライバーの[Googleグループ](https://groups.google.com/forum/?fromgroups#!forum/node-mongodb-native)を掘り下げていました。誰もが何らかの形で接続の再利用を提案しているようです(彼らのほとんどは実際にはオプションBのようなものを示唆している)。 – ArturoVM

+0

一方、私は、同じ接続の下ですべてを行うことは、ノードの非同期性の目的を破って、ブロックしていると読んでいます。 – ArturoVM

答えて

11

MongoJSが好きです。これは、Mongoをデフォルトのコマンドラインと非常によく似た方法で使用できるようにします。これは、Mongoの公式ドライバのラッパーに過ぎません。あなたは一度DBを開いて、使用するコレクションを指定するだけです。ノードを--harmony-proxiesで実行すると、コレクションを省略することもできます。

var db = require('mongojs').connect('mydb', ['posts']); 

server.get('/posts', function (req, res) { 
    db.posts.find(function (err, posts) { 
    res.send(JSON.stringify(posts)); 
    }); 
}); 
+0

私は実際にそれを愛する! :Dありがとうございました。しかし、私は答えのコメントでGijsに言ったように、同じ接続の下ですべてを行うとコードがブロックされるということをどこかで読んでいます。これが本当かどうか知っていますか? – ArturoVM

+0

私はそうは思わない。それは目的を破るだろう。私はデータベースへの接続がソケットを通して行われると信じています。ソケットは、ネットワーク上で、Streamsでファイルを読むときにNodeが行うのと非常によく似ています。 ReadStreamは小さなチャンクでファイルを読み取り、イベントを受け取ったときにイベントを発生させます。私はソケットがネットワークチャンクと同じように動作すると思う。 http://nodejs.org/api/net.html#net_class_net_socket – juandopazo

+0

を参照してください。ブロックまたは非ブロックはAPIによって異なります。したがって、上記の例は、 'server.get(...)'がDBに正常に接続されるまでブロックされないという意味でブロックされているように見えます(純粋に見えるものです。 MongoJSと一緒に)。しかし、おそらくDBを*必要とすることを考えれば、それは必ずしもすべて悪いわけではありませんが、実行に時間がかかるこれらの依存関係の多くがある場合は、先物/ @scttnlsnのソリューションのような約束/コールバック。 – Gijs

6
  • HTTPリクエストが処理される前に、DBは、開口部を終了されるという保証はありませんので、Aは素晴らしいアイデアではありません。オプション(これは非常に低いです付与)
  • は、Cが不それ以降も理想的ではありません。オプションDB接続を開閉します。

私がこれを処理する方法は、deferreds /約束を使用しています。そこノードのために利用可能な異なる約束ライブラリの束がありますが、基本的な考え方は、このような何かをすることです:

var promise = new Promise(); 

db.open(function(err, db) { 
    // handle err 
    promise.resolve(db); 
}); 

server.get('/api/something', function doSomething(req, res, next) { 
    promise.then(function(db) 
     // do something 
    }); 
}); 

私はマングースは漠然とこれに似ているように、接続を処理すると信じています。

+0

ありがとうございます。私はモンゴセを調べましたが、それは公式ドライバーとはまったく違うことをしていないようです。接続を開いたときにイベントが発生し、接続されていない間に操作がバッファされるため、気にする必要はありません。しかし、私は約束のことを見ていきます:) – ArturoVM

+0

MongoJSという図書館は、実際には約束を使ったほうがはるかに良い例です(先物と呼ばれています)。 – scttnlsn

関連する問題