【问题标题】:next.js and mongodb atlas - getting "Connections % of configured limit has gone above 80" alertnext.js 和 mongodb atlas - 获取“已配置限制的连接百分比已超过 80”警报
【发布时间】:2021-03-25 04:59:52
【问题描述】:

我在 MongoDB Atlas 上看到了很多关于此警报的帖子和文章(“已配置限制的连接数百分比已超过 80”),但无法弄清楚如何在我的 Next.js 应用程序中解决它。

我在处理函数之外创建我的数据库连接。我用了一个中间件withDatabase.js

const client = new MongoClient(process.env.MONGODB_URI, { 
    useNewUrlParser: true, 
    useUnifiedTopology: true 
});

const addDbToRequest = (handler, req, res) => {
    req.db = req.connection.db("MYDBNAME");
    return handler(req, res);
};

const withDatabase = handler => async (req, res) => {
    if (!client.isConnected()) {
        await client.connect();
    }
    req.connection = client;
    return addDbToRequest(handler, req, res);
};

export default withDatabase;

此中间件包装 API 端点处理程序。

现在,如果我在每个 API 处理程序完成后关闭连接,如下所示:

    const { connection } = req;
    if (connection) {
        connection.close();
    }

然后,我在对同一个 api 处理程序的第二次请求时收到错误:

MongoError: Topology is closed, please connect

如果我没有关闭连接,我会在我的电子邮件中收到此警报(使用一小段时间后):

Connections % of configured limit has gone above 80

在 Next.js 应用程序中使用 MongoDB Atlas 的最佳实践是什么?

谢谢!

【问题讨论】:

    标签: mongodb next.js mongodb-atlas


    【解决方案1】:

    连接应该被重用,原因如下:

    1. 在每个 API 请求上打开和关闭数据库连接都很慢。
    2. 很难扩展。假设您同时向每个用户发出几个 API 请求,当应用获得更多用户时,您将很快达到相同的连接数限制。

    How do I manage MongoDB connections in a Node.js web application?

    默认 MongoClient 配置将每个池的最大连接数 (poolSize) 设置为 5。因此,如果您只运行一个应用程序实例并检查客户端是否已连接,那么您在 MongoDB Atlas 中看到的连接数不应超过 5 个,就像您一样。

    if (!client.isConnected()) {
      await client.connect();
    }
    

    注意,Next.js 在开发模式 (next dev) 的每个请求上都会“重新启动”,它似乎会影响 MongoClient 缓存并创建许多连接。但是在生产模式下,您应该不会遇到此问题。

    【讨论】:

    • 所以问题是开发模式,因为我没有关闭连接..
    • “快速刷新”怎么样?然后在开发模式下,每次代码更改都会触发新连接,这将很快达到 MongoDB Atlas 限制
    • 直到我了解到 poolSize 配置之前,这没有任何意义。正如 MongoDb 指南所述 poolSize: Specifies the maximum size of the instance connection pool. 因此,当您执行 client.connect() 时,这是设置一个连接“池”(可以包含多个连接)。开发人员可能应该对connect 函数有不同的措辞(例如连接池可能是“ICP”),因此用户不会认为它只是建立一个与数据库的连接。 MongoDb Atlas 似乎不跟踪连接池,只跟踪连接。
    【解决方案2】:

    为了解决在 Next 的开发模式下达到的最大连接数问题,我发现将重用/缓存的 client 对象写入全局 Node 对象允许它在刷新之间持续存在。

    const MongoClient = require('mongodb').MongoClient;
    
    async function useMongoClient() {
      if (!this.client) {
        this.client = await MongoClient.connect(process.env.MONGODB_URI, {
          useUnifiedTopology: true,
        });
      }
    
      return this.client;
    }
    
    module.exports = useMongoClient;
    

    【讨论】:

    • 在我的环境中“this”出现未定义,我无法将任何参数附加到它...“global”是一个东西,但我试图创建“global.cachedDB”并且它总是出现未定义。
    猜你喜欢
    • 2019-11-20
    • 2015-09-15
    • 2022-01-27
    • 2014-07-07
    • 2014-01-29
    • 1970-01-01
    • 2010-10-03
    • 2020-08-16
    • 1970-01-01
    相关资源
    最近更新 更多