如何在NodeJS中维护mongo客户端



我正在努力了解如何在节点应用程序中维护mongo客户端。我的第一个想法是为每一个收藏检索创建一个客户端。类似这样的东西:

const getCollection = (collectionName) => {
return MongoClient.connect(url, {useNewUrlParser: true, useUnifiedTopology: true})
.then((client) => {
const database = client.db(databaseName);
return database.collection(collectionName);
})
.catch((err) => {
console.log(err);
});
};

然后使用返回的promise进行查询。像这样:

const executeFind = (collectionName, query, projection, skip, limit) => {
return getCollection(collectionName)
.then(collection => {
return collection.find(query, {projection: projection})
.skip(skip)
.limit(limit)
.toArray();
})
.catch((err) => {
console.log(err);
});
};

这种方法的问题是,在运行应用程序时,与mongo的开放连接数量迅速增加,导致数据库操作出现问题,并发出大量警报。

我认为连接增加的可能原因:

  • 大池大小-我尝试将maxPoolSize=5添加到URL。还将poolSize: 5添加到options(MongoClientconnect函数的第二个参数。连接数仍然会爆发
  • 缺少连接关闭-我现在找不到文档,但我在某个地方读到连接是由客户端自己管理的,所以不需要考虑使用close()。但无论如何,我试图在collection.find()返回结果后将代码重写为客户端close()。我得到Cannot use a session that has ended

除此之外,我没有任何其他想法来以一种在资源分配/运行方面高效的方式维护mongo客户端。我想听听两者的答案:

  • 1.在这种方法中,究竟可以做些什么来避免开放连接的增加
  • 2.维护mongo客户端的更通用/最佳/最佳实践方式是什么
  • 检查下面的mongo-db池连接片段

MongoClient.connect(url, {
poolSize: 10
// other options can go here
}, function(err, db) {
global.mongodb = db;
});

  • 为了处理连接,我们需要编写自定义代码,比如检查连接是否存在,如果不创建新的连接

我可以部分回答我的问题。我能够用client.close()解决连接增加的问题。主要问题似乎是promise缺少await,因此close()导致了意外行为(close()有时发生在实际调用查询之前,并导致session already closed错误(。

上述方法(每次调用都打开和关闭连接(的问题在于速度相当慢。

仍在寻找最佳维护客户的一般答案

更新

我终于找到了一个解决方案,它不会打开高得离谱的连接,而且也是最优的。

这里的技巧是在数据访问层(或者数据库代码所在的任何地方(声明并调用异步函数,该函数将设置数据库对象。类似这样的东西:

let database;
(async () => {
const client = await MongoClient.connect(url, {poolSize: 150, useNewUrlParser: true, useUnifiedTopology: true});
database = client.db(databaseName);
})();

然后在任何地方重复使用数据库对象,如下所示:

database.collection(collectionName).insertMany(documents);

池和连接打开/关闭由client处理。就最优性而言,它要快得多(正如预期的那样(。不确定在dao中调用全局数据库或立即函数(尽管,由于文件是用require导入的,所以不应该多次调用(是否是最佳做法,但它确实做到了。

最新更新