因为不了解 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);
});

这种感觉好像是这样的……我觉得在某个页面上也看到过类似的描述……如果有做错什么,请指出来……

广告
将在 10 秒后关闭
bannerAds