如何使用Mongoose创建缓存的MongoDB连接?
Mongoose 实现 MongoDB 连接缓存的正确方式?
我之前用下面的方式连接MongoDB,但每次请求都会创建新连接:
import mongoose from "mongoose" const connectDb = async () => { return mongoose.connect(process.env.MONGO_URI, (err) => { if (err) { console.log(err); } else { console.log("connected to mongoDB successfully"); } }); } export default connectDb
了解到缓存连接的概念后,我实现了下面的代码,目前运行正常,但不确定是否正确:
import mongoose from 'mongoose' const MONGODB_URI = process.env.MONGO_URI // 如果未提供MongoDB地址则抛出错误 if (!MONGODB_URI) { throw new Error( '请在.env.local中定义MONGODB_URI环境变量' ) } // 首次连接时将连接缓存到全局变量,避免每次请求重复创建连接 let cached = global.mongoose // 若没有缓存连接,初始化连接状态和Promise容器 if (!cached) { cached = global.mongoose = { conn: null, promise: null } } // 创建连接数据库的异步函数 async function connectDb() { // 若已有缓存连接,直接返回旧连接 if (cached.conn) { return cached.conn } // 若没有正在进行的连接Promise,创建新连接请求 if (!cached.promise) { const opts = { bufferCommands: false, } cached.promise = mongoose.connect(MONGODB_URI, {useNewUrlParser: true}).then((mongoose) => { return mongoose }) } try { cached.conn = await cached.promise } catch (e) { cached.promise = null throw e } return cached.conn } export default connectDb
你的实现是正确的,且符合Mongoose连接复用的最佳实践
这份代码的核心逻辑完全贴合Mongoose在服务端(尤其是Serverless无服务器环境)避免重复创建连接的设计思路,拆解来看:
- 全局缓存存储
- 使用
global.mongoose缓存连接状态,Node.js模块本身会被缓存,但全局对象能跨模块、跨请求保留连接信息,避免每次导入或请求时重新初始化连接逻辑。
- 使用
- 避免重复连接
- 优先检查
cached.conn:如果已有可用连接,直接返回,跳过连接流程。 - 再检查
cached.promise:如果存在正在进行的连接Promise,复用该Promise,防止并发请求触发大量重复连接请求。
- 优先检查
- 错误处理机制
- 连接失败时重置
cached.promise为null,确保下次调用connectDb时能重新发起连接尝试,不会一直复用失败的Promise。
- 连接失败时重置
可选优化点
- 新版本Mongoose(v6+)中,
useNewUrlParser、useUnifiedTopology等选项已默认开启,可从连接配置中移除,简化代码。 - 可添加连接状态日志,方便排查问题,比如连接成功/失败时打印对应信息。
内容的提问来源于stack exchange,提问作者Max Vhanamane
相关产品推荐
相关产品推荐

