使用MongoDB打开连接



我正在用NextJS开发一个项目,并用MongoDB存储我的数据,并且MongoDB连接有问题。

连接逻辑很简单:

  1. 用户连接到页面
  2. 页面联系我的API以获取页面信息
  3. 我的API使用中间件从MongoDB获取数据

根据逻辑,我只有一个用户连接到mongoDB(系统用户(。但问题是我在MongoDB中打开了很多连接(见图(。我的中间件似乎没有关闭连接。这是我的代码有问题还是MongoDB逻辑有问题?

附言:当我关闭我的本地项目MongoDB连接数降至0。

下面是我的中间件示例,系统在其中连接MongoDB。

import { MongoClient } from 'mongodb';
import nextConnect from 'next-connect';
const client = new MongoClient(process.env.mongoApiUrl, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
async function database(req, res, next) {
if (!client.isConnected()) await client.connect();
req.dbClient = client;
req.db = client.db('test');
return next();
}
const middleware = nextConnect();
middleware.use(database);
export default middleware;

根据我的代码,如果我们有一个开放连接-使用开放连接。我从这个mongodb教程中获得了上面的代码

我该怎么办?

问题是API路由是serverless,这意味着它们是在需要时创建的,并在底层无服务器托管结构认为合适时销毁。因此,您需要找到一种方法来避免为每个请求创建到数据库的连接

/**
* Global is used here to maintain a cached connection across hot reloads
* in development. This prevents connections from growing exponentially
* during API Route usage.
*/
let cached = global.mongo
if (!cached) {
cached = global.mongo = { conn: null, promise: null }
}
export async function connectToDatabase() {
if (cached.conn) {
return cached.conn
}
if (!cached.promise) {
const opts = {
useNewUrlParser: true,
useUnifiedTopology: true,
}
cached.promise = MongoClient.connect(MONGODB_URI, opts).then((client) => {
return {
client,
db: client.db(MONGODB_DB),
}
})
}
cached.conn = await cached.promise
return cached.conn
}

您可以在Next.js示例存储库中看到完整的示例

在这里,我重新设计了中间件以使用缓存的连接。(感谢这个答案(

import { MongoClient } from 'mongodb';
import nextConnect from 'next-connect';
const mongoClient = new MongoClient(process.env.mongoApiUrl, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
//with serverless we need to use cache to prevent re-opening connection
let cached = global.mongo

if (!cached) {
cached = global.mongo = { conn: null, promise: null }
}
async function database(req, res, next) {
if (!cached.promise) {
cached.promise = mongoClient.connect().then((client) => {
return {
client,
db: client.db(process.env.MONGODB_DB),
}
})
cached.conn = await cached.promise
}
req.dbClient = cached.conn.client
req.db = cached.conn.db
return next();
}
const middleware = nextConnect();
middleware.use(database);

export default middleware;

如果在下一次连接时有新的更改,这就是我在以前的代码的基础上使其工作的方式

import { MongoClient } from 'mongodb';
import nc from 'next-connect';
const MONGODB_URI = process.env.MONGODB_URI
const MONGODB_DB = process.env.MONGODB_DB
const mongoClient = new MongoClient(MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
//with serverless we need to use cache to prevent re-opening connection
let cached = global.mongo

if (!cached) {
cached = global.mongo = { conn: null, promise: null }
}
async function database(req, res, next) {
if (!cached.promise) {
cached.promise = mongoClient.connect().then((client) => {
return {
client,
db: client.db(MONGODB_DB),
}
})
cached.conn = await cached.promise
}
req.dbClient = cached.conn.client
req.db = cached.conn.db
return next();
}
const middleware = nc();
middleware.use(database);

export default middleware;

和我的.env文件:

MONGODB_URI=mongodb://localhost:27017/
MONGODB_DB=hotelcrud

最新更新