因为不了解 MongoDB 的连接池,所以进行了调查
很抱歉,我缺乏MongoDB等NoSQL的工作经验,最近正在学习中。我正在使用Express+Typescript项目的模板,通过创建Express应用来连接MongoDB。
我正在使用MongoDB的官方驱动程序,但是在连接数据库部分,我经常看到以下类似的描述。
MongoClient.connect('mongodb://localhost:27017/db', (err, db) => {
db.collection('mycollection').insertOne(xxxxxx);
db.close();
})
简单地说,每次都连接和关闭连接吗?是没有连接池的吗?我试验证明了这一点的实际文章。
我随意地调查了一下,发现可以在MongoClient中指定连接池的大小,而且即使调用了connect方法,也不一定每次都会建立连接,而是复用了连接池中的连接。
我会尝试各种实验。
暂时先试试看
export async function connect() {
const client = await MongoClient.connect(MONGODB_URI, {
minPoolSize: 40, // コネクションプール数を40にしてみる
maxPoolSize: 40,
});
return client.db('example');
}
connect(); // 接続
结果 (jié guǒ)
> db.serverStatus().connections
{
"current" : 42, // ローカルの接続もあるので多少ずれるけどOK
"available" : 777,
"totalCreated" : 304,
"active" : 2,
"exhaustIsMaster" : 0,
"exhaustHello" : 0,
"awaitingTopologyChanges" : 1
}
当您启动Express并调用connect时,会创建40个连接。
无论调用connect多少次,是否会重复使用最初创建的连接池?
直觉上,似乎需要重复使用最初调用的MongoClient.connect的返回值(client)。
为了试验,我会尝试调用40次connect。
export async function connect() {
const client = await MongoClient.connect(MONGODB_URI, {
minPoolSize: 40,
maxPoolSize: 40,
});
return client.db('example');
}
for (let i = 0; i < 40; i++) {
connect();
}
结果
> db.serverStatus().connections
{
"current" : 485, // 40余裕で超えてる!!
"available" : 334,
"totalCreated" : 8256,
"active" : 2,
"exhaustIsMaster" : 0,
"exhaustHello" : 0,
"awaitingTopologyChanges" : 1
}
确实是这样的,虽然不太算得上是一个正确的计算,但总之好像不太适合每次都调用connect。
换句话说,可能的做法是将connect的结果放入全局变量中,启动Express → 然后共享给大家。一定是这样。
总结
export async function connect() {
const client = await MongoClient.connect(MONGODB_URI, {
minPoolSize: 40,
maxPoolSize: 40,
});
}
export let db: Db; // これをみんなで使いまわす
// connectに成功したらdbを変数に格納
// その後サーバを起動する
connect().then((d) => {
db = d;
server.listen(port);
});
这种感觉好像是这样的……我觉得在某个页面上也看到过类似的描述……如果有做错什么,请指出来……