生产环境(Vercel)中MongoDB Atlas配置引发超时错误
操作MongoDB Atlas集群集合时随机出现查询/保存超时错误
错误日志示例
Error en authorize: MongooseError: Operation `users_profiles.findOne()` buffering timed out after 10000ms at Timeout.<anonymous> (/var/task/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:185:23) at listOnTimeout (node:internal/timers:569:17) at process.processTimers (node:internal/timers:512:7)
问题核心
该错误并非每次操作都会触发,约半数操作出现问题,触发时间完全随机。
项目环境与结构
采用NextJS Pages Router构建,数据库连接相关文件结构如下:
/database//schemas//Connections.ts:返回两个数据库连接Promise的连接函数/models.ts:将每个Schema分配到对应连接
Connections.ts 代码
import mongoose from "mongoose"; export const runtime = "nodejs"; interface DatabaseConnections { mvpDB: mongoose.Connection; chatbotDB: mongoose.Connection; } let cached: { conn: DatabaseConnections | null; promise: Promise<DatabaseConnections> | null } = global.mongoose; if (!cached) { cached = global.mongoose = { conn: null, promise: null }; } export const connectDBs = async () => { const MVP_URI = process.env.DATABASE_SECRET_MVP; const CHATBOT_URI = process.env.DATABASE_SECRET_CHATBOT; if (!MVP_URI || !CHATBOT_URI) { throw new Error("MongoDB URIs not found in environment variables"); } if (cached.conn) { return cached.conn; } if (!cached.promise) { const opts = { bufferCommands: true, minPoolSize: 2, maxPoolSize: 4, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000, connectTimeoutMS: 10000, maxIdleTimeMS: 270000, retryWrites: true, retryReads: true }; cached.promise = (async () => { try { const mvpDB = await mongoose.createConnection(MVP_URI, opts); const chatbotDB = await mongoose.createConnection(CHATBOT_URI, opts); mvpDB.on('error', (error) => { console.error('MVP DB connection error:', error); cached.conn = null; cached.promise = null; }); chatbotDB.on('error', (error) => { console.error('Chatbot DB connection error:', error); cached.conn = null; cached.promise = null; }); return { mvpDB, chatbotDB }; } catch (error) { cached.promise = null; throw error; } })(); } try { cached.conn = await cached.promise; return cached.conn; } catch (error) { cached.promise = null; throw error; } };
models.ts 代码
import mongoose from "mongoose" import { connectDBs } from "./dbNewType"; import { user } from "./schemas/userschema_app"; import { conversationSchema } from "./schemas/conversations"; import { dietSchema } from "./schemas/DietSchema"; import { users_answers } from "./schemas/UserAnswers"; import { customerSchema } from "./schemas/customerSchema"; import { subscriptionSchema } from "./schemas/subscriptionSchema"; const { mvpDB, chatbotDB } = await connectDBs(); // Check if models exist before defining them export const Users_Profile = mvpDB.models.users_profiles || mvpDB.model('users_profiles', user); export const Users_Answers = mvpDB.models.users_answers || mvpDB.model('users_answers', users_answers); export const Diet = mvpDB.models.Diet || mvpDB.model('Diet', dietSchema); export const Customer = mvpDB.models.Customer || mvpDB.model('Customer', customerSchema); export const Subscription = mvpDB.models.Subscription || mvpDB.model('Subscription', subscriptionSchema); export const Conversation = chatbotDB.models.Conversation || chatbotDB.model('Conversation', conversationSchema); export default { Users_Profile, Users_Answers, Diet, Conversation, Customer, Subscription }
使用方式
使用模型时,先导入模型,再调用users_profiles.findOne()这类方法。
内容的提问来源于stack exchange,提问作者BeastDevMoney
相关产品推荐
相关产品推荐

