3

単一サーバーのセットアップで、ドライバーからイベントを受け取ります。

mongoose.connect('mongodb://localhost/mydb');
mongoose.connection.on('disconnected', function() {...});
mongoose.connection.on('error', function(err) {...});

レプリカ セット ( mongoose.connect('mongodb://localhost:27017/mydb,mongodb://localhost:27018/mydb');) を使用している場合、接続されているすべてのセット メンバーをシャットダウンしても、同じイベントはトリガーされません。

私はネイティブ ドライバーの内部構造に詳しくないので、これがバグなのか、それともこの状態を手動で検出する必要があるのか​​疑問に思っています。

Mongoose 3.6.17 (mongodb ドライバー 1.3.18) を使用しています

Sans mongoose、同じ結果でこれを試しました(レプリカセットからのイベントはありません)。

require('mongodb').MongoClient.connect("mongodb://localhost:27017,localhost:27018/mydb", function(err, db) {
    if (db) {
        db.on('disconnected', function() {
            console.log('disconnected');
        }).on('error', function(err) {
            console.log('error');
        });
    }            
});
4

3 に答える 3

2

私はMongooseでも同様の問題を抱えており、SOでも尋ねました。最近、Mongoose GitHub リポジトリでこの問題を発見し、それがドライバー リポジトリでこの問題を引き起こしました。

Mongo ドライバーはこれらのイベントを 2 回以上発行していませんでしたが、今日、v1.3.19の単一接続でこれが修正されました。
今のところ「治りません」のようです。

于 2013-08-21T17:56:10.403 に答える
0

私は最終的に次のことをしました:

  1. auto_reconnect=true に設定しました
  2. アプリケーションが初めてデータベースに接続するまで、切断して再接続します。切断して再接続しないと、キューに入れられたクエリは実行されません。接続が少なくとも 1 回確立された後、これらのキューに入れられたクエリは完了し、その後...

単一接続の場合: 1. (mongodb を 1.3.19 に使用するために) mongoose をフォークしたため、エラーが複数回トリガーされます。2.接続エラーをキャッチし、アプリに切断を認識させ、あきらめてパニックになるか、アプリが再接続されるまで再試行します。これを行う方法は、キューに入れられないコマンドを使用して、x ミリ秒ごとにサーバーに ping を実行することです。

var autoReconnect = mongoose.connection.db.serverConfig.isAutoReconnect;
mongoose.connection.db.serverConfig.isAutoReconnect = function(){return false;};
mongoose.connection.db.executeDbCommand({ping:1}, {failFast: true}, function(err) {
    if (!err) {
        // we've reconnected.
    }
});
mongoose.connection.db.serverConfig.isAutoReconnect = autoReconnect;

レプリカ セットの場合、エラーを検出するまで x ミリ秒ごとに上記の ping を使用してマングース接続をポーリングすることになりました。エラーが検出された場合は、ローカル アプリの状態を切断に設定し、上記の再接続ポーリング ループに入ります (2.)。

ここに関連するビットの要点があります。https://gist.github.com/jsas/6299412

于 2013-08-21T20:01:55.517 に答える
0

これは、 の厄介な矛盾/見落としですmongoose

特に、開発用に単一のサーバー設定を使用し、本番環境でレプリカ セットを使用しているマイクロサービスを開発する場合。

mongooseこれが、接続のステータスを正確に追跡する方法です。

let alive = false;

function updateAlive() {
  return mongoose.connection
    && mongoose.connection.readyState === mongoose.STATES.connected
    // This is necessary because mongoose treats a dead replica set as still "connected".
    && mongoose.connection.db.topology.connections().length > 0;
}

mongoose.connection.on('connected', () => {
  updateAlive();
  // I think '.topology' is available on even single server connections.
  // The events just won't be emitted.
  mongoose.connection.db.topology.on('joined', () => updateAlive());
  mongoose.connection.db.topology.on('left', () => updateAlive());
});

mongoose.connection.on('disconnected', () => {
  updateAlive();
});
于 2020-12-28T19:14:13.920 に答える