Nodejs中如何在node使用mongodb的连接池

Nodejs中如何在node使用mongodb的连接池

最近用node读取更新mongodb的文档,发现: Error: db object already connecting, open cannot be called multiple times 的错误出现的次数越来越多,但是我每一次open()后都有close()。。听说用连接池管理mongodb的链接可以优化性能,不需要close()了,所以在这里想请教各位前辈,如何使用连接池解决这个问题,优化mongodb的性能?

PS:我知道有一个mongose可以解决这个问题,但是很想知道不用它应该怎么做。。


10 回复

Node.js 中如何在 Node 使用 MongoDB 的连接池

在使用 Node.js 操作 MongoDB 时,如果频繁地打开和关闭数据库连接,可能会遇到如下的错误:

Error: db object already connecting, open cannot be called multiple times

为了避免这种情况,并提高应用的性能,我们可以利用 MongoDB 的内置连接池功能来管理数据库连接。MongoDB 驱动程序(mongodb)本身就支持连接池机制,我们只需要正确配置即可。

示例代码

首先,确保你已经安装了 mongodb 包:

npm install mongodb

接下来,我们可以通过以下方式创建一个连接池:

const { MongoClient } = require('mongodb');

async function run() {
    const uri = "mongodb+srv://<username>:<password>@cluster0.mongodb.net/test?retryWrites=true&w=majority";
    const client = new MongoClient(uri, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        poolSize: 10 // 设置连接池大小
    });

    try {
        await client.connect();
        console.log("Connected to MongoDB");

        const database = client.db('testdb');
        const collection = database.collection('testcollection');

        // 执行你的操作
        const result = await collection.insertOne({ name: 'John Doe' });
        console.log(result);

        // 不需要显式关闭连接,连接池会自动管理
    } catch (error) {
        console.error("Error:", error);
    } finally {
        // 如果你想手动关闭连接池,可以在这里调用
        // await client.close();
    }
}

run().catch(console.error);

解释

  • poolSize: 这个选项用于设置连接池的最大连接数。你可以根据实际需求调整这个值。

  • client.connect(): 连接 MongoDB 服务器。这里我们使用了 await 关键字来等待连接完成。

  • 自动管理连接: 在上面的代码中,我们没有显式地调用 client.close() 来关闭连接。这是因为连接池会自动管理连接的生命周期。当我们不再需要连接时,连接池会将其返回到池中以供后续操作使用。

通过这种方式,我们可以避免频繁打开和关闭连接带来的性能问题,并且简化了代码逻辑。如果你的应用需要处理大量的并发请求,这种方法尤其有效。


我觉得吧 node这种单线程靠回调的甚至有时候没法准确控制流程的物件,mongodb打开了就不要关闭了吧。一直用一个db 连接就好了。

恩恩已经了解了。但是欢迎各位前辈甩下一些资料~~

一个连接的话如果连接lost或者阻塞了不就挂了?pool还是比较好的,不过mongodb 我没用过,实在不行自己写个,或者用这个generic-pool

多谢前辈指点~~

You open do MongoClient.connect once when your app boots up and reuse the db object. It’s not a singleton connection pool each .connect creates a new connection pool.

使用node-mongodb-native,这是官方为nodejs提供的驱动。这个库本本身就实现了pool管理,所以不用另外考虑连接池。使用上可以通过配置链接url或server的属性设置连接池大小。可以在程序初始化时创建一个全局的访问client,也可以自己再封装一次。所有通过这个client的发出的mongo操作请求,驱动底层都会自动分配链接。由于底层是用c/c++实现的,所以不用担心代码会阻塞。具体如何创建可以参见http://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html#mongoclient-connect

使用 mongoosejs

在Node.js中使用MongoDB时,可以通过连接池来管理数据库连接,以避免重复连接和提高性能。以下是如何配置和使用MongoDB的官方驱动程序mongodb中的连接池。

示例代码

首先,确保安装了mongodb模块:

npm install mongodb

然后,你可以通过以下方式配置连接池并连接到MongoDB:

const { MongoClient } = require('mongodb');

async function main() {
    const uri = 'mongodb://localhost:27017'; // MongoDB的连接字符串
    const client = new MongoClient(uri, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        maxPoolSize: 50, // 设置最大连接池大小
        minPoolSize: 5,  // 设置最小连接池大小
        poolSize: 10     // 设置连接池大小(如果设置,优先于maxPoolSize)
    });

    try {
        await client.connect(); // 连接到MongoDB服务器
        console.log("Connected successfully to server");

        const db = client.db('yourDatabaseName'); // 选择数据库
        const collection = db.collection('yourCollectionName'); // 选择集合

        // 在这里进行读取、插入、更新等操作
        // 例如:await collection.insertOne({ name: "John Doe" });
        
    } catch (err) {
        console.error("An error occurred:", err);
    } finally {
        // 不需要手动关闭连接,连接池会自动管理连接
        // await client.close();
    }
}

main().catch(console.error);

解释

  • maxPoolSize, minPoolSize, 和 poolSize 是用于配置连接池大小的参数。

    • maxPoolSize 是连接池的最大连接数。
    • minPoolSize 是连接池的最小连接数,通常保持较低以节约资源。
    • poolSize 如果设置,则优先于 maxPoolSize,定义连接池的具体大小。
  • 使用连接池后,你无需每次操作都调用 client.connect()client.close()。客户端对象会在首次调用 connect() 后保持活动状态,并且可以在后续的操作中复用这些连接。

  • 当所有活动的连接都被占用时,连接池将创建新的连接(直到达到最大连接数)。当连接不再被需要时,它们会被放回池中,而不是立即关闭。

这种方式可以显著减少由于频繁打开和关闭连接而导致的性能问题,并提供更稳定的连接管理。

回到顶部