2

main.js

var http = require('http');
var UserModel = require('./models/user.js');
var server = http.createServer(function(req, res){
  UserModel.create({
  }), function(e, o){
    if(e) { console.log(e); } else {
    } console.log(o); }
  });
}).listen(3000);

connection.js

var mongo = require('mongodb');

module.exports = {
    dbMain: new mongo.Db('main', new mongo.Server('127.0.0.1', 27017, { auto_reconnect: true }, {})),
    dbLog: new mongo.Db('log', new mongo.Server('127.0.0.1', 27017, { auto_reconnect: true }, {}))
};

/models/user.js

var mongodb = require('mongodb');
var db = require('./connections.js').dbMain;

module.exports = {
  create: function(newData, callback){
    db.open(function(e, db){
      db.collection('users', function(e, collection){
        collection.insert(newData, callback);
      });
    });
  }
}

上記のコードを使用すると、サーバーがクラッシュし、リクエストが2回目に受信されても​​、データベース接続が開いたままになっているため、Users.create関数にdb.closeを追加します。

  create: function(newData, callback){
    db.open(function(e, db){
      db.collection('users', function(e, collection){
        collection.insert(newData, function(e, o){
          db.close(); // Voila.
          callback(e, o);
        });
      });
    });
  }

この段階では、複数の接続が開いているため、サーバーがクラッシュする可能性があります。これが発生する理由や方法はわかりませんが、発生します。

プロジェクトをモデルに編成するにはどうすればよいですか(Mongooseを使用したくないので、検証はモデルではなく別のレイヤーで行われるため、Mongooseはやり過ぎになります)。また、プロジェクトで接続を処理するにはどうすればよいですか?

4

2 に答える 2

8

これをすべてうまくまとめたライブラリを作成できます。つまり、データベースへの接続が1つだけ開かれ、2番目の要求に対して同じ(開いた)接続が返されます。1秒あたり1000以上を取得している場合、これは次のようになります。メイクまたはブレークの問題(つまり、リクエストごとに接続を再度開かない)...

users.js

var connections = require('./connections.js');

var serverCache = connections('127.0.0.1', 27017); 

module.exports = {
  create: function(newData, callback){
    serverCache('main', 'users', function(e, collection){
      collection.insert(newData, callback);
    })
  }
}

connection.js

var mongo = require('mongodb');

// a mongo connection cache
// pass in host & port
// it returns a function accepting dbName, collectionName & callback
var mongoCache = function(host, port){

  // keep our open connections
  var mongoDatabases = {};

  var ensureDatabase = function(dbName, readyCallback){
    // check if we already have this db connection open
    if(mongoDatabases[dbName]){
      readyCallback(null, mongoDatabases[dbName]);
      return;
    }

    // get the connection
    var server = new mongo.Server(host, port, {auto_reconnect: true});

    // get a handle on the database
    var db = new mongo.Db(dbName, server);
    db.open(function(error, databaseConnection){
      if(error) throw error;

      // add the database to the cache
      mongoDatabases[dbName] = databaseConnection;

      // remove the database from the cache if it closes
      databaseConnection.on('close', function(){
        delete(mongoDatabases[dbName]);
      })

      // return the database connection
      readyCallback(error, databaseConnection);
    })
  }

  var ensureCollection = function(dbName, collectionName, readyCallback){

    ensureDatabase(dbName, function(error, databaseConnection){
      if(error) throw error;

      databaseConnection.createCollection(collectionName, function(error, collection) {
        if(error) throw error;

        // return the collection finally
        readyCallback(error, collection);
      })

    })
  }

  return ensureCollection;
}

module.exports = mongoCache;
于 2012-08-20T14:31:25.350 に答える
2

現在、複数のhttpリクエストでグローバル接続を使用しています。以前は、MongoDBへの複数の接続を作成し、接続ごとに1つをランダムに取得する複雑なライブラリを作成しました。

後で私はネイティブドライバーが私のためにそれをすることができることを発見しました、それはかなりきちんとしています。現在、私は単一のオブジェクトを使用しており、ドライバーはどの接続にクエリを送信するかを選択します。

var srvOpts = {
    auto_reconnect: true,
    poolSize: 10,
};

var conn = new Mongo.Server("localhost", 27017, srvOpts),
    db = new Mongo.Db("dbname", conn, {});

db.open(function (){});

できる限り、これは素晴らしいアイデアです。そのアイデアを、使用しているRedisドライバーにコピーすることを考えていますが、時間が足りないため、すぐに実行できるとは思えません。

于 2012-08-20T15:04:56.023 に答える