そもそもの所でNode.jsの強みが消えますので
コネクションは基本的に閉じずに運用してください。
というわけでコネクションを閉じない運用の提案をしていきます。
MongoDBにはコネクションプールという機能が存在します
参考サイト: 公式サイトドキュメント#コネクションプール
MongoClient connection pooling
A Connection Pool is a cache of database connections maintained by the driver so that connections can be re-used when new connections to the database are required. To reduce the number of connection pools created by your application, we recommend calling MongoClient.connect once and reusing the database variable returned by the callback:
和訳
MongoClient コネクションプール
コネクションプールとは、ドライバが管理するデータベース接続のキャッシュのことで、 データベースへの新しい接続が必要になったときに接続を再利用できるようにします。アプリケーションが作成するコネクションプールの数を減らすには、 MongoClient.connect を一度コールしてコールバックで返されたデータベース変数を再利用することをお勧めします。
解説しますと、Webサーバは同時に何百人というユーザがWebサービスを利用しようと訪れる可能性があります。
その何百人が一斉にrouter.get("/*", fn)
に押し寄せたとすると、
MongooDBサーバにその何百人分のコネクションよこせが来るので最初の3人だけ受け付けて、残り数百人はエラーという結果になりかねません。
(MongoDBというアプリもそこまでヤワな作りでは無いでしょうし、実際にはそれなりに上手くやるでしょうけどね)
その対策としてコネクションプールという機能が存在します。
プールは学校とかにある水が張っていて泳げるプールを指します。
水面にビート板のように接続状態のコネクションを投げ入れておき、利用者が取れるような仕組みになっています。
(MySQL等の他のデータベースにもある、わりとよくある作戦です)
コネクションプールを使いNode.jsとMongoDBを接続させますと、
予め3本の接続を予約しておいてすぐ使える状態にします。
(この時の接続本数は設定により自由に変更が可能です)
100人のユーザーが訪れた場合、最初の3人に接続を使わせておき
残り97人には「ちょっと待ってろ」と待たせます。
3本の問い合わせは、問い合わせ完了後、コネクションプールに接続を返しに来ます。
接続がコネクションプールに帰ってきたら4人目、5人目という風に
順番待ちしている人たちに接続を使わせるという仕組みになります。
コードに関してはドキュメントの下にあります
軽くコメントで注釈入れつつ、一緒に見ていきましょう。
js
1var express = require('express');
2var mongodb = require('mongodb');
3var app = express();
4
5var MongoClient = require('mongodb').MongoClient;
6// 予めコネクションプール用の変数を宣言しておく
7var db;
8
9// 初期処理としてMongoDBのコネクションを確保する
10MongoClient.connect("mongodb://localhost:27017/integration_test", function(err, database) {
11 if(err) throw err;
12
13 // MongoDBとの接続が完了したらコネクションプール用の変数へ代入
14 db = database;
15
16 // MongoDBとの接続が完了してからExpress.jsを立ち上げるのだ
17 app.listen(3000);
18 console.log("Listening on port 3000");
19});
20
21// 改めてExpress.jsの設定を記述していく
22app.get("/", function(req, res) {
23 // コネクションプール利用時の書き方は特に変わらない
24 // こうするだけで勝手に順番待ちを作って解決してくれる
25 db.collection("replicaset_mongo_client_collection").find({}, function(err, docs) {
26 docs.each(function(err, doc) {
27 if(doc) {
28 console.log(doc);
29 }
30 else {
31 // コネクションを閉じる記述の必要無し
32 res.end();
33 }
34 });
35 });
36});
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。