Node.js 本机 mongodb 主节点关闭时与副本集失去连接

Node.js native mongodb losing connection with replica set when primary goes down

我有一个使用本机 node.js mongodb 包的系统(由于遗留代码,更改为 mongoose 将是最后的选择)当前系统使用一个独立的 mongo 实例,但我想转而使用副本集。为了测试这一点,我有一个本地 (Win 7) mongo 实例 运行 作为主要实例,在远程(即物理上远程)机器上有一个辅助实例和一个仲裁程序 运行 raspberry pi(使用 arch linux 64 位)。

问题是,当我关闭当前设置为主的 mongod 进程而不是驱动程序重新连接到新的主进程时,它失败了 出现 ECONNRESET 错误。

除此之外,副本集似乎正常运行,所有节点都 "up" 并且处于正确的状态,并在节点关闭时相应地进行调整。

我从 node.js mongodb 包的 v2.2.31 开始,最近使用 v3.0.4 进行了测试,没有任何变化。

最初我在本地有 mongodb v3.4.3,在远程有 3.4.9,所以如果是版本不匹配问题(这似乎不太可能),我将它设置为在两端都使用 v3.6.2但同样的问题仍然存在。

这是配置问题还是只是误解了故障转移过程的自动化程度。非常感谢任何帮助。

示例输出:

$ node compiled/replset.js
-> joined secondary

===[ item 1 of 90 ]=========================================================
'ASC3498349'
===[ item 2 of 90 ]=========================================================
'YHD9848935'
===[ item 3 of 90 ]=========================================================
'PLS3098423'
===[ item 4 of 90 ]=========================================================
'JDJ2340982'
===[ item 5 of 90 ]=========================================================
'MDK3489346'
===[ item 6 of 90 ]=========================================================
'LDE3948849'
-> all servers connected

-> left primary

{ Error: read ECONNRESET
    at _errnoException (util.js:1024:11)
    at TCP.onread (net.js:615:25)
  name: 'MongoNetworkError',
  message: 'read ECONNRESET',
  stack: 'Error: read ECONNRESET\n    at _errnoException (util.js:1024:11)\n at TCP.onread (net.js:615:25)' }

测试程序:

import * as util from "util";
import * as mongodb from 'mongodb';

const { ReplSet } = require('mongodb-topology-manager');

process.on('unhandledRejection', (err) => {
    console.log(err);
    process.exit();
});

(async () => {

    const client = await mongodb.MongoClient.connect('mongodb://user:pass@<HOST1>:<PORT1>,<HOST2>:<PORT2>,<HOST3>:<PORT3>/test?replicaSet=rs&authMechanism=DEFAULT&authSource=admin');

    client.topology.on('left', (data: any) => {
        console.log('-> left', data);
        console.log(``);
    });
    client.topology.on('joined', (data: any) => {
        console.log('-> joined', data);
        console.log(``);
    });
    client.on('fullsetup', () => {
        console.log('-> all servers connected');
        console.log(``);
    });

    const totalCount = 90
    let count = 1;
    const INTERVAL = 1000;
    const db = client.db('test');
    const col = db.collection('items');
    const timer = setTimeout(onTimer, INTERVAL);

    async function onTimer() {

        const item = await col.findOne({}, {
            skip: count,
        });
        console.log(`===[ item ${count} of ${totalCount} ]===========================================================================`);
        console.log(util.inspect(item, { colors: true, depth: null }));
        count++;

        if (count > totalCount) {
            client.close();
            console.log('done');
        }
        else {
            setTimeout(onTimer, INTERVAL);
        }
    }
})();

抱歉,可能是只见树木不见森林!只需处理从查找中抛出的 ECONNRESET 异常并继续,一切都很好。