MongoClient抛出MongoError:服务器实例池已损坏

时间:2019-02-04 17:51:18

标签: node.js mongodb

我在SO上看到这些帖子描述了此错误。其中大多数是由于JavaScript是异步的,并且在回调之外调用了mongoClient.close()的原因。那不是我的情况,但是我不知道还有什么原因。

const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";
const mongoClient = new MongoClient(url, {
    useNewUrlParser: true
});

module.exports = class Mongo {
    insertOne(article) {
        mongoClient.connect((err, client) => {
            const db = client.db('grabber');
            db.collection("zr").insertOne(article, (err, res) => {
                if (err) throw err;
                mongoClient.close();
            });
        });
    };
}

1 个答案:

答案 0 :(得分:0)

我发现您在mongoClient.connect()方法中打开insertOne(),并在该方法中还以mongoClient.close()作为全局变量来调用mongoClient

我的直觉是:

  • 还有另一种方法调用mongoClient,该方法已被该方法关闭,或者
  • 您两次致电insertOne(article)

我可以确认第二个原因是最可能的原因。这是我尝试的代码:

const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://localhost:27017/";
const mongoClient = new MongoClient(url, {
    useNewUrlParser: true
});

class Mongo {
    insertOne(article) {
        mongoClient.connect((err, client) => {
            const db = client.db('grabber');
            db.collection("zr").insertOne(article, (err, res) => {
                if (err) throw err;
                mongoClient.close();
            });
        });
    };
};

x = new Mongo()
setTimeout(function() { x.insertOne({'a': 1}); }, 1000);
setTimeout(function() { x.insertOne({'a': 2}); }, 2000);

两个setTimeout在那里,以确保两个insertOne()被一个接一个地调用。结果:

MongoError: server instance pool was destroyed

当前代码的结构方式,每次调用insertOne()时,节点驱动程序都会创建一个新的连接池。这不是最佳选择,它会阻止节点驱动程序利用连接池。

与其在mongoClient.connect()内部调用insertOne(),而是在class Mongo之外全局调用它。将全局连接对象(从mongoClient.connect()返回的对象)本身而不是mongoClient对象传递给您的insertOne()方法。