You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js项目Netlify/Vercel MongoDB连接504超时错误解决方法

解决Next.js项目闲置后数据库连接超时引发的504错误

问题说明

网站闲置一段时间后首次加载,Netlify或Vercel会返回504超时错误,重新加载后恢复正常。核心原因是数据库初始连接耗时过长,超出了平台的超时限制。当前使用的Mongoose连接函数及相关信息如下:

import mongoose from 'mongoose'

const MONGODB_URI = process.env.MONGO_URL

if (!MONGODB_URI) {
  throw new Error(
    'Please define the MONGODB_URI environment variable inside .env.local'
  )
}

let cached = global.mongoose

if (!cached) {
  cached = global.mongoose = { conn: null, promise: null }
}

async function db() {
  if (cached.conn) {
    return cached.conn
  }

  if (!cached.promise) {
    const opts = {
      bufferCommands: false,
    }

    cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
      return mongoose
    })
  }

  try {
    cached.conn = await cached.promise
  } catch (e) {
    cached.promise = null
    throw e
  }

  return cached.conn
}

export default db

调用方式:await db()
MongoDB URL格式:mongodb+srv://*********@cluster0.7xbw7v5.mongodb.net/?retryWrites=true&w=majority

优化方案

1. 调整Mongoose连接参数,维持长连接

修改连接配置,通过连接池和心跳设置避免连接被闲置断开:

const opts = {
  bufferCommands: false,
  maxPoolSize: 10, // 设置连接池最大容量
  minPoolSize: 2, // 保留最小空闲连接数,防止连接全部释放
  serverSelectionTimeoutMS: 5000, // 缩短服务器选择超时时间,快速失败重试
  socketTimeoutMS: 45000, // 延长Socket超时时间,避免活跃连接被误断开
  heartbeatFrequencyMS: 10000, // 每10秒发送一次心跳,保持连接活跃状态
}

2. 提前预热数据库连接

在项目启动阶段提前触发连接初始化,避免首次请求时才建立连接:

  • 在Next.js的pages/_app.js的getInitialProps中执行一次await db()
  • 或在常用API路由的初始化逻辑里提前调用连接函数,让连接缓存提前生效

3. 利用定时请求维持连接活跃

针对平台的函数闲置休眠机制,设置定时请求唤醒服务:

  • 用定时任务工具(如简单的云函数定时任务)每隔几分钟访问一次项目的API路由,触发连接初始化,防止连接因闲置被断开
  • 注意:部分平台免费版可能对这类请求有次数限制,需参考官方规则

4. 优化连接缓存的有效性检查

在现有缓存逻辑基础上,增加连接活跃性校验,避免返回失效连接:

async function db() {
  if (cached.conn) {
    // 检查缓存连接是否仍活跃
    try {
      await cached.conn.db.admin().ping()
      return cached.conn
    } catch (e) {
      // 连接失效,重置缓存
      cached.conn = null
      cached.promise = null
    }
  }

  if (!cached.promise) {
    const opts = {
      bufferCommands: false,
      maxPoolSize: 10,
      minPoolSize: 2,
      serverSelectionTimeoutMS: 5000,
      socketTimeoutMS: 45000,
      heartbeatFrequencyMS: 10000,
    }

    cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
      return mongoose
    }).catch((e) => {
      cached.promise = null
      throw e
    })
  }

  try {
    cached.conn = await cached.promise
  } catch (e) {
    cached.promise = null
    throw e
  }

  return cached.conn
}

内容的提问来源于stack exchange,提问作者Nooblantis District

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 14:15:49