如何在 NodeJS 中维护 mongo 客户端
How to maintain mongo client in NodeJS
我正在尝试了解如何在节点应用程序中维护 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
(MongoClient 的 connect
函数的第二个参数。连接数仍然爆裂。
- 缺少连接关闭 - 我现在找不到该文档,但我在某处读到连接由客户端本身管理,因此无需考虑
close()
连接它们。但是无论如何,我尝试在 collection.find()
returns 结果之后将代码重写到 close()
客户端。我得到 Cannot use a session that has ended
除此之外,我没有任何其他想法来维护 mongo 客户端,以便在资源 allocation/running 方面保持高效。我想听听关于这两个问题的答案:
- 1.在这种方法中究竟可以做什么来避免打开连接增加?
- 2。更重要的是 general/optimal/best 练习维护 mongo 客户端的方法。
- 检查以下代码段以了解 mongo 数据库池连接。
MongoClient.connect(url, {
poolSize: 10
// other options can go here
}, function(err, db) {
global.mongodb = db;
});
- 为了处理连接,我们需要编写自定义代码,比如检查连接是否存在,如果不存在则创建一个新连接。
我可以部分回答我的问题。
我能够通过 client.close()
解决连接增加问题。主要问题似乎是缺少承诺 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);
池化和连接 open/close 由 client
处理。就最优性而言,它的速度更快(正如预期的那样)。不确定在 dao 中调用全局数据库或即时函数是否是最佳实践(虽然,由于文件是使用 require
导入的,因此不应多次调用),但它确实可以解决问题。
我正在尝试了解如何在节点应用程序中维护 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
(MongoClient 的connect
函数的第二个参数。连接数仍然爆裂。 - 缺少连接关闭 - 我现在找不到该文档,但我在某处读到连接由客户端本身管理,因此无需考虑
close()
连接它们。但是无论如何,我尝试在collection.find()
returns 结果之后将代码重写到close()
客户端。我得到Cannot use a session that has ended
除此之外,我没有任何其他想法来维护 mongo 客户端,以便在资源 allocation/running 方面保持高效。我想听听关于这两个问题的答案:
- 1.在这种方法中究竟可以做什么来避免打开连接增加?
- 2。更重要的是 general/optimal/best 练习维护 mongo 客户端的方法。
- 检查以下代码段以了解 mongo 数据库池连接。
MongoClient.connect(url, {
poolSize: 10
// other options can go here
}, function(err, db) {
global.mongodb = db;
});
- 为了处理连接,我们需要编写自定义代码,比如检查连接是否存在,如果不存在则创建一个新连接。
我可以部分回答我的问题。
我能够通过 client.close()
解决连接增加问题。主要问题似乎是缺少承诺 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);
池化和连接 open/close 由 client
处理。就最优性而言,它的速度更快(正如预期的那样)。不确定在 dao 中调用全局数据库或即时函数是否是最佳实践(虽然,由于文件是使用 require
导入的,因此不应多次调用),但它确实可以解决问题。