mongodbデータベースデバッグの問題:‘db object already connecting,open cannot be called multiple times’
6147 ワード
マイクロブログシステムのデバッグ中:
(1)ログインログインログインは正常に表示され、登録時にネットワーク接続が突然停止したが、ユーザー名とパスワードがデータベースに格納され、undefined is not a functionとエラーが発生した.
エラーは主にUseを指す.jsの一言:mongodb.close();
ソリューション:mongodbバージョンは1.3.0より高いため、mongodbと考えられます.close()この関数は定義されていないので関数として使用し、mongodbを直接使用します.close()という言葉の注釈を外すと、システムは正常に登録して実行することができます.
(2)mongodbを注釈する.close()以降mongodbでよく発生するエラーdb object already connecting,open cannot be called multiple times’
Nodejsは非同期スレッドであり、いずれにしてもdbを用いる.Open()ですが、データベースを開くたびにアクセスが完了するたびに、パンツdbを閉じる必要があります.close();
前のデバッグでデータベースのシャットダウンを注記すると、データベースは常に開いていて、データベースがまだ閉じていないのにここで開くとdb object already connecting、open cannot be called multiple times'のエラーが発生します.
この時点でのソリューション:
a:データベースが開く前にmongodbを直接前に追加します.close()は、データベースが開くたびにデータベースが閉じられ、デバッグされたシステムが正常に動作していることを確認します.
b.open and close動作からopen once and reuse anywhereに変更します.プログラムが起動するとdb.Openは一度にhttpリクエストごとにデータベースに直接アクセスし、dbを破棄する.open/db.closeという2つの余計な操作
元のopen+closeメソッド:
dbを捨てるopen/db.closeという2つのループに対応した操作の方法で,最初から開いている状態にする.
このように変更すると、同時アクセス>5の場合、同時に使用可能な最下位のデータベース接続が5しかないため、ブロックが発生する可能性があります.
実際にシーンを適用する場合、dbオブジェクトを直接参照するのは良いアイデアではありません.デフォルトでは、dbのpoolSize=5は、同時性が5しかないことを意味しますが、同時性を高めるにはpoolSizeを10に引き延ばしますか?20? 50? 100? NO,我々に必要なのは接続数を動的に調整できる接続プールであり,ピーク時の接続数の要求を満たすだけでなく,mongodbの内蔵接続プールのように固定接続数を維持するのではなく,空き期間にアイドル接続を解放することができる.どうしよう?車輪を再発明しますか?いいえ、既存の接続プールモジュールgenericを再利用します.pool、コードは以下の通りです
c.mongodbデータベースに対して1つの問題があります:リフレッシュが速すぎて、あるいは複数のユーザーが同時にデータベースにアクセスして、データベースが閉じる暇がなくて、db object already connecting、open cannot be called multiple timesというエラーが発生します
mongoseを使用すると、mongoseではデータベースに接続するとdbがopen状態になり、アクセス時に開くルールがなく、閉じるルールがないため、mongoseを使用するとこのエラーは発生しません.
これはmongodbの操作方法です.
これはmongoseでの操作方法です
以上a.b.cはdb object already connecting,open cannot be called multiple times’問題を解決するための3つのスキームのまとめである
(1)ログインログインログインは正常に表示され、登録時にネットワーク接続が突然停止したが、ユーザー名とパスワードがデータベースに格納され、undefined is not a functionとエラーが発生した.
エラーは主にUseを指す.jsの一言:mongodb.close();
ソリューション:mongodbバージョンは1.3.0より高いため、mongodbと考えられます.close()この関数は定義されていないので関数として使用し、mongodbを直接使用します.close()という言葉の注釈を外すと、システムは正常に登録して実行することができます.
(2)mongodbを注釈する.close()以降mongodbでよく発生するエラーdb object already connecting,open cannot be called multiple times’
Nodejsは非同期スレッドであり、いずれにしてもdbを用いる.Open()ですが、データベースを開くたびにアクセスが完了するたびに、パンツdbを閉じる必要があります.close();
前のデバッグでデータベースのシャットダウンを注記すると、データベースは常に開いていて、データベースがまだ閉じていないのにここで開くとdb object already connecting、open cannot be called multiple times'のエラーが発生します.
この時点でのソリューション:
a:データベースが開く前にmongodbを直接前に追加します.close()は、データベースが開くたびにデータベースが閉じられ、デバッグされたシステムが正常に動作していることを確認します.
b.open and close動作からopen once and reuse anywhereに変更します.プログラムが起動するとdb.Openは一度にhttpリクエストごとにデータベースに直接アクセスし、dbを破棄する.open/db.closeという2つの余計な操作
元のopen+closeメソッド:
var server_options={};
var db_options={w:-1};
var mongodb = require("mongodb"),
mongoserver = new mongodb.Server('localhost', 27017,server_options ),
db = new mongodb.Db('test', mongoserver, db_options);
var http=require('http');
var server=http.createServer(function(req,res){
db.open(function(err,db){
if(err)return console.error(err);
console.log('* mongodb connected');
db.collection('foo').save({test:1},function(err,result){
res.end(JSON.stringify(result,null,2));
db.close();
});
})
});
server.listen(8080,function(){
console.log('server listen to %d',this.address().port);
});
setTimeout(function(){
//http.get('http://localhost:8080',function(res){console.log('request ok')});
//http.get('http://localhost:8080',function(res){console.log('request ok')});
},2000);
dbを捨てるopen/db.closeという2つのループに対応した操作の方法で,最初から開いている状態にする.
var server_options={'auto_reconnect':true,poolSize:5};
var db_options={w:-1};
var mongodb = require("mongodb"),
mongoserver = new mongodb.Server('localhost', 27017,server_options ),
db = new mongodb.Db('test', mongoserver, db_options);
db.open(function(err,db){
if(err)throw err;
console.info('mongodb connected');
});
var http=require('http');
var server=http.createServer(function(req,res){
db.collection('foo').save({test:1},function(err,result){
res.end(JSON.stringify(result,null,2));
});
});
server.listen(8080,function(){
console.log('server listen to %d',this.address().port);
});
setTimeout(function(){
http.get('http://localhost:8080',function(res){console.log('request ok')});
http.get('http://localhost:8080',function(res){console.log('request ok')});
},2000);
このように変更すると、同時アクセス>5の場合、同時に使用可能な最下位のデータベース接続が5しかないため、ブロックが発生する可能性があります.
実際にシーンを適用する場合、dbオブジェクトを直接参照するのは良いアイデアではありません.デフォルトでは、dbのpoolSize=5は、同時性が5しかないことを意味しますが、同時性を高めるにはpoolSizeを10に引き延ばしますか?20? 50? 100? NO,我々に必要なのは接続数を動的に調整できる接続プールであり,ピーク時の接続数の要求を満たすだけでなく,mongodbの内蔵接続プールのように固定接続数を維持するのではなく,空き期間にアイドル接続を解放することができる.どうしよう?車輪を再発明しますか?いいえ、既存の接続プールモジュールgenericを再利用します.pool、コードは以下の通りです
var http=require('http'),
mongodb = require("mongodb"),
poolModule = require('generic-pool');
var pool = poolModule.Pool({
name : 'mongodb',
create : function(callback) {
var server_options={'auto_reconnect':false,poolSize:1};
var db_options={w:-1};
var mongoserver = new mongodb.Server('localhost', 27017,server_options );
var db=new mongodb.Db('test', mongoserver, db_options);
db.open(function(err,db){
if(err)return callback(err);
callback(null,db);
});
},
destroy : function(db) { db.close(); },
max : 10,//
idleTimeoutMillis : 30000,
log : false
});
var server=http.createServer(function(req,res){
pool.acquire(function(err, db) {
if (err) {
res.statusCode=500;
res.end(JSON.stringify(err,null,2));
} else {
db.collection('foo').save({test:1},function(err,result){
res.end(JSON.stringify(result,null,2));
pool.release(db);
});
}
});
});
server.listen(8080,function(){
console.log('server listen to %d',this.address().port);
});
setTimeout(function(){
http.get('http://localhost:8080',function(res){console.log('request ok')});
http.get('http://localhost:8080',function(res){console.log('request ok')});
},2000);
c.mongodbデータベースに対して1つの問題があります:リフレッシュが速すぎて、あるいは複数のユーザーが同時にデータベースにアクセスして、データベースが閉じる暇がなくて、db object already connecting、open cannot be called multiple timesというエラーが発生します
mongoseを使用すると、mongoseではデータベースに接続するとdbがopen状態になり、アクセス時に開くルールがなく、閉じるルールがないため、mongoseを使用するとこのエラーは発生しません.
これはmongodbの操作方法です.
User.get = function get(username, callback) {
mongodb.open(function(err, db) {
if (err) {
return callback(err);
}
// users
db.collection('users', function(err, collection) {
if (err) {
mongodb.close();
return callback(err);
}
// name username
collection.findOne({name: username}, function(err, doc) {
mongodb.close();
if (doc) callback (err, doc);
else callback (err, null);
});
});
});
};
これはmongoseでの操作方法です
User.get = function get(username, callback) {
users.findOne({name:username}, function(err, doc){
if (err) {
return callback(err, null);
}
return callback(err, doc);
});
};
以上a.b.cはdb object already connecting,open cannot be called multiple times’問題を解決するための3つのスキームのまとめである