next.js 和 mongodb atlas - 收到“配置限制的连接百分比已超过 80”警报

use*_*396 7 mongodb next.js mongodb-atlas

我在 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;

Run Code Online (Sandbox Code Playgroud)

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

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

    const { connection } = req;
    if (connection) {
        connection.close();
    }
Run Code Online (Sandbox Code Playgroud)

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

MongoError: Topology is closed, please connect
Run Code Online (Sandbox Code Playgroud)

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

Connections % of configured limit has gone above 80
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Nik*_*lev 8

由于以下原因,应重用该连接:

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

如何在 Node.js Web 应用程序中管理 MongoDB 连接?

2022 年更新:

import { MongoClient } from 'mongodb'

const uri = process.env.MONGODB_URI
const options = {}

let client
let clientPromise

if (!process.env.MONGODB_URI) {
  throw new Error('Please add your Mongo URI to .env.local')
}

if (process.env.NODE_ENV === 'development') {
  // In development mode, use a global variable so that the value
  // is preserved across module reloads caused by HMR (Hot Module Replacement).
  if (!global._mongoClientPromise) {
    client = new MongoClient(uri, options)
    global._mongoClientPromise = client.connect()
  }
  clientPromise = global._mongoClientPromise
} else {
  // In production mode, it's best to not use a global variable.
  client = new MongoClient(uri, options)
  clientPromise = client.connect()
}

// Export a module-scoped MongoClient promise. By doing this in a
// separate module, the client can be shared across functions.
export default clientPromise
Run Code Online (Sandbox Code Playgroud)

2022年之前

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

if (!client.isConnected()) {
  await client.connect();
}
Run Code Online (Sandbox Code Playgroud)

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