首页 > 解决方案 > 重新连接后,Mongoose 连接计数到 MongoDB Atlas

问题描述

我们有以下问题:7 台服务器连接到 MongoDB Atlas,考虑到连接池,MongoDB 显示的连接数量(减去来自集群、备份、记录器等的所有服务连接)为 35。这没关系:7 台服务器,每台 5 个连接。但是突然 MongoDB 被重新启动(不知道为什么,我猜是内部的东西)并且每个服务器的连接数变成了 100+。所以如果一开始是35,现在是900+。以前的连接似乎停留在某个地方。编码:

const RECONNECT_TIMEOUT = 5000;

mongoose.Promise = Promise; //  Set mongoose to use ES6 Promises.
const db = mongoose.connection;

const connect = () => {
    mongoose
        .connect(DB, {
            useNewUrlParser: true,
            useFindAndModify: false,
            useUnifiedTopology: true,
            useCreateIndex: true,
            autoReconnect: true,
            reconnectInterval: 1000,
            reconnectTries: Number.MAX_VALUE,
            poolSize: 5
        })
        .catch(() => {
            //  No further treatment required: Connection events are already doing this
        });
};
if (process.env.NODE_ENV !== 'test') {
    db.on('error', err => {
        logger.error(`MongoDB connection error:\n`, err);
    });

    db.on('connected', () => {
        logger.info('Connected to MongoDB');
    });

    db.once('open', () => {
        logger.info('MongoDB connection opened');
    });

    db.on('reconnected', () => {
        logger.info('MongoDB reconnected');
    });

    db.on('disconnected', () => {
        void db.close();
        void mongoose.disconnect(() => {
            logger.error(`MongoDB disconnected. Reconnecting in ${RECONNECT_TIMEOUT / 1000} s...`);
            setTimeout(() => connect(), RECONNECT_TIMEOUT);
        });
    });
}

connect();

我以这种方式重新创建了问题:在本地运行服务器,它连接并建立一定数量的连接(池大小为 5,默认情况下也是如此)。然后我只是禁用并启用网络适配器。然后我看到这个查询到 admin db 的连接数量: const connections = (await db.command({ currentOp: 1, $all: 1 })).inprog;

首先,在服务器启动之前,当我执行此请求时,我有 1 个活动连接(没关系)。然后,当服务器连接时,我看到 6 个连接(1 个用于查询,5 个用于池 - 这没关系)。然后,在我重新启动网络适配器后,我看到连接数量开始增加:10、17、26、33 ......它们开始在某处累积,如果在本地我看到 - 一段时间后 - 连接数量会自行减少一点,但是从我们的服务器到 Atlas 云中的 MongoDB 的连接已经保持 900+ 超过 24 小时。

为什么有这么多连接,这种行为可以修复吗?我们连接 MongoDB 的方式有问题吗?

标签: node.jsmongodbmongoose

解决方案


阅读 mongod/mongos 日志以查看正在建立连接的驱动程序和客户端主机/IP。

启用查询日志记录以查看正在发送的查询。

使用 currentOp 等来查看服务器上发生了什么。


推荐阅读