Vercel部署NodeJS项目访问MongoDB遇504 Gateway Timeout求助
问题:Node.js项目部署Vercel后MongoDB访问504超时
项目结构
/configs db.config.js /routes testRoutes.js index.js vercel.json
核心代码
index.js
const express = require('express'); const connectToDb = require('./configs/db.config'); const cors = require('cors'); const path = require('path'); const testRouter = require('./routes/testRoutes'); const app = express(); const PORT = process.env.PORT || 5000; app.use(cors()); app.use(express.json()); app.use('/', express.static(path.join(__dirname, '/public'))); app.use('/test', testRouter.getUsers); connectToDb() .then((res) => { app.listen(PORT, () => { console.log(`Server is running on port: ${PORT}`); }); }) .catch((err) => { console.log(err); }); module.exports = app;
db.config.js
const {MongoClient} = require('mongodb'); const uri = `mongodb+srv://${process.env.DB_USER}:` + `${process.env.DB_PASSWORD}@${process.env.DB_CLUSTER_URL}/` + `?retryWrites=true&w=majority&appName=${process.env.DB_APP_NAME}`; const client = new MongoClient(uri); let database; const connectToDb = async () => { if (database) { return database; } try { await client.connect(); console.log('Connected to MongoDB'); database = client.db(process.env.DB_NAME); return database; } catch (error) { console.log(error); } }; module.exports = connectToDb;
testRoutes.js
const connectToDb = require('../configs/db.config'); const getUsers = async (req, res) => { try { let db = await connectToDb(); const collection = db.collection(process.env.DB_COLLECTION); const data = await collection.find({}).toArray(); res.send(data); } catch (error) { console.error('Error accessing the database', error); res.status(500).send('Failed to fetch data'); } }; module.exports = { getUsers, };
vercel.json
{ "version": 2, "builds": [{ "src": "index.js", "use": "@vercel/node" }], "routes": [{ "src": "/(.*)", "dest": "index.js" }] }
问题现象
本地运行时访问http://localhost:5000/test可正常返回数据库记录,但部署到Vercel后访问该路由出现504 Gateway Timeout错误,Vercel日志无有效报错信息。
可能原因及解决方向
1. MongoDB网络访问权限未开放Vercel IP
MongoDB Atlas默认仅允许本地IP访问,Vercel服务器IP动态变化,需在MongoDB控制台调整权限:
- 登录MongoDB Atlas控制台,进入目标集群
- 左侧菜单选择
Network Access,点击Add IP Address - 测试阶段可输入
0.0.0.0/0(允许所有IP),生产环境建议添加Vercel官方公布的IP段
2. Vercel环境变量未正确配置
本地.env文件的数据库凭证不会自动同步到Vercel,需手动添加:
- 登录Vercel控制台进入项目,选择
Settings->Environment Variables - 添加所有所需变量:
DB_USER、DB_PASSWORD、DB_CLUSTER_URL、DB_APP_NAME、DB_NAME、DB_COLLECTION - 确保变量名、值与本地完全一致,无拼写错误
3. Vercel Serverless特性兼容问题
Vercel的Serverless Function不支持长期保持数据库连接,当前单例连接逻辑需调整:
- 修改
db.config.js,避免长期持有连接,每次请求重新建立或检查连接:const {MongoClient} = require('mongodb'); const connectToDb = async () => { const uri = `mongodb+srv://${process.env.DB_USER}:${process.env.DB_PASSWORD}@${process.env.DB_CLUSTER_URL}/?retryWrites=true&w=majority&appName=${process.env.DB_APP_NAME}`; const client = new MongoClient(uri); try { await client.connect(); console.log('Connected to MongoDB'); return client.db(process.env.DB_NAME); } catch (error) { console.log(error); await client.close(); throw error; } }; module.exports = connectToDb; - 移除
index.js中的app.listen()调用,Vercel会自动处理请求,无需手动启动服务器
4. MongoDB连接超时配置过短
冷启动时Vercel建立连接可能耗时较长,可增加连接超时参数:
const client = new MongoClient(uri, { serverSelectionTimeoutMS: 5000, connectTimeoutMS: 5000 });
5. 增加日志排查
在getUsers函数中添加更详细的日志,方便定位问题:
const getUsers = async (req, res) => { try { console.log('Checking environment variables:', { DB_USER: !!process.env.DB_USER, DB_CLUSTER_URL: !!process.env.DB_CLUSTER_URL, DB_NAME: !!process.env.DB_NAME }); let db = await connectToDb(); console.log('Connected to database:', db.databaseName); const collection = db.collection(process.env.DB_COLLECTION); console.log('Accessing collection:', process.env.DB_COLLECTION); const data = await collection.find({}).toArray(); console.log('Fetched data count:', data.length); res.send(data); } catch (error) { console.error('Full error details:', error); res.status(500).send('Failed to fetch data'); } };
内容的提问来源于stack exchange,提问作者gfcf14
相关产品推荐
相关产品推荐

