部署在Vercel的Next.js应用/api/webhooks POST请求504超时
解决Vercel上Clerk-MongoDB Webhook 504超时问题
核心原因
Vercel Serverless Function默认超时时间为10秒,你的Webhook在处理Clerk事件时,同步等待MongoDB的createUser/updateUser/deleteUser操作完成,导致请求超过10秒触发504错误。
代码层面解决方案
1. 异步处理数据库操作(优先推荐)
Webhook无需向Clerk返回数据库操作结果,只需快速返回200确认接收即可。将数据库操作改为异步执行,不阻塞响应:
修改api/webhooks/route.ts中的事件处理逻辑:
// 处理user.created事件 if (eventType === "user.created") { const { id, email_addresses, image_url, username, first_name, last_name } = evt.data; // 异步执行数据库操作,不等待结果 void(async () => { try { await createUser({ clerkId: id, name: `${first_name}${last_name ? ` ${last_name}` : ""}`, username: username!, email: email_addresses[0].email_address, picture: image_url, }); } catch (err) { console.error("创建用户失败:", err); } })(); return NextResponse.json({ message: "OK" }); } // 处理user.updated事件 if (eventType === "user.updated") { const { id, email_addresses, image_url, username, first_name, last_name } = evt.data; void(async () => { try { await updateUser({ clerkId: id, updateData: { name: `${first_name}${last_name ? ` ${last_name}` : ""}`, username: username!, email: email_addresses[0].email_address, picture: image_url, }, path: `/profile/${id}`, }); } catch (err) { console.error("更新用户失败:", err); } })(); return NextResponse.json({ message: "OK" }); } // 处理user.deleted事件 if (eventType === "user.deleted") { const { id } = evt.data; void(async () => { try { await deleteUser({ clerkId: id! }); } catch (err) { console.error("删除用户失败:", err); } })(); return NextResponse.json({ message: "OK" }); }
2. 优化MongoDB操作性能
- 给用户集合的
clerkId字段添加唯一索引,加速查询、更新和删除操作:// 在MongoDB shell或ODM(如Mongoose)中执行 db.users.createIndex({ clerkId: 1 }, { unique: true }); - 检查
createUser/updateUser/deleteUser中的代码,移除不必要的查询或数据处理逻辑,减少耗时。
3. 复用MongoDB连接
确保数据库连接采用单例模式,避免每次Webhook请求都新建连接:
// lib/mongodb.ts示例 import { MongoClient } from "mongodb"; let client: MongoClient | null = null; export async function getMongoClient() { if (!client) { client = new MongoClient(process.env.MONGODB_URI!); await client.connect(); } return client; }
Vercel平台层面解决方案
1. 调整Serverless Function超时时间
若使用Vercel Pro/Enterprise计划,可将函数超时时间从默认10秒延长至最大60秒:
- 进入Vercel项目 → Settings → Functions
- 在"Timeout"选项中设置更长时间(如30秒)
2. 改用Edge Functions
Edge Functions的超时时间为30秒(免费版也支持),适合处理耗时稍长的请求。只需在route.ts顶部添加:
export const runtime = "edge";
注意:Edge环境有部分Node.js API限制,需确保createUser等操作兼容Edge环境(如避免使用fs等仅Node.js可用的模块)。
3. 确认中间件配置
你的middleware.ts已将/api/webhooks加入ignoredRoutes,确保中间件不会对Webhook请求做额外认证处理,减少不必要的耗时。当前配置无需调整。
内容的提问来源于stack exchange,提问作者Kekoo
相关产品推荐
相关产品推荐

