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)

没有猫鼬,我尝试了相同的结果(没有来自副本集的事件)。

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 GitHub 存储库上发现了这个问题,导致驱动程序存储库出现了这个问题

Mongo 驱动程序没有多次发出任何这些事件,今天这个问题已经在 v1.3.19 上针对单个连接进行了修复。
目前看来,这是一个“无法解决”的问题。

于 2013-08-21T17:56:10.403 回答
0

我最终做了以下事情:

  1. 我设置 auto_reconnect=true
  2. 在应用程序第一次连接到数据库之前,我断开连接并重新连接。如果我不断开连接并重新连接,任何排队的查询都不会运行。在至少建立一次连接后,那些排队的查询确实完成了,然后......

对于单个连接: 1. forked mongoose(使用 mongodb 到 1.3.19)所以错误会被多次触发。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 回答