代码之家  ›  专栏  ›  技术社区  ›  andrey.shedko

MongoClient throw MongoError:服务器实例池已销毁

  •  0
  • andrey.shedko  · 技术社区  · 5 年前

    我在网上看到了这些描述这个错误的帖子。其中大部分原因是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 回复  |  直到 5 年前
        1
  •  1
  •   kevinadi    5 年前

    我注意到你打开了门 mongoClient.connect() insertOne() 方法,并调用 mongoClient.close() 在该方法中 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() )而不是 反对你的观点 insertOne() 方法