Vercel 的部署体验以"简单流畅"著称,但生产环境中仍可能遇到各种各样的问题:从构建阶段 TypeScript 报错到 Function 运行时超时,从 Prisma 生成失败到自定义域名 404,从内存溢出到路由冲突。本文基于大量真实项目的排障经验,按构建阶段 → 运行阶段 → 网络层 → 集成层四层排查,给你一套系统性的诊断流程和修复方案。
一、构建阶段故障
1.1 构建失败的通用排查流程
1. 查看 Vercel Dashboard → Deployments → 点击失败的部署 → Build Logs
2. 定位第一个 ERROR/FAIL 行(通常后续错误是该错误的连锁反应)
3. 用 Ctrl+F 搜索 "error:" / "failed:" / "cannot find" 等关键词
4. 根据错误类型 → 对应下方章节排查
5. 本地复现:`npm run build`(不是 `npm run dev`,dev 和 build 行为不同)
1.2 TypeScript / ESLint 错误导致构建失败
错误示例:
Failed to compile.
./src/app/page.tsx:12:5
Type error: Type '{ blogs: any[]; }' is not assignable to type 'IntrinsicAttributes & Props'.
排查步骤:
# 1. 本地完整构建(development 会跳过类型检查)
npm run build
# 2. 单独检查类型
npx tsc --noEmit
# 3. 如果确认类型检查过于严格,临时放宽(不推荐长期使用)
// tsconfig.json
{
"compilerOptions": {
"strict": false, // 临时关闭严格模式
"noEmit": true
}
}
// next.config.js
module.exports = {
typescript: {
ignoreBuildErrors: true, // ⚠️ 仅临时用
},
eslint: {
ignoreDuringBuilds: true, // ⚠️ 仅临时用
},
};
注意:
ignoreBuildErrors只是跳过 TS 检查,问题代码仍然会让生产环境出错。建议先用它过构建,然后在本地用tsc --noEmit真修复。
1.3 依赖安装失败
错误示例:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
修复:
# 1. 删除 lock 文件和 node_modules,重新安装
rm -rf node_modules package-lock.json
npm install
# 2. 如果使用 pnpm
rm -rf node_modules pnpm-lock.yaml
pnpm install
# 3. 检查 Node.js 版本(Vercel 默认使用 package.json engines 或项目设置)
# 在 Vercel Dashboard → Settings → General → Node.js Version 中设置
1.4 找不到模块(Module Not Found)
错误示例:
Error: Cannot find module '@/lib/prisma'
排查:
// tsconfig.json / jsconfig.json
{
"compilerOptions": {
"paths": {
"@/*": ["./*"] // 或 ["./src/*"],对应你的目录结构
}
}
}
// package.json — 确认没有漏装依赖
{
"dependencies": {
"@prisma/client": "^5.0.0"
}
}
1.5 Prisma 生成失败
错误示例:
Error: @prisma/client did not initialize yet.
原因:prisma generate 没有执行,导致 @prisma/client 不可用。
修复:
// package.json
{
"scripts": {
"build": "prisma generate && next build",
"postinstall": "prisma generate" // 确保 npm install 时自动执行
}
}
# 确认 prisma/schema.prisma 存在
ls prisma/schema.prisma
# 确认生成后文件存在
ls node_modules/.prisma/client/
1.6 环境变量缺失
错误示例:
Error: Missing environment variable DATABASE_URL
排查:
# 1. 本地检查 .env
env | grep DATABASE_URL
# 2. Vercel Dashboard → Settings → Environment Variables
# 确认 Production 和 Preview 环境都配置了
# 3. 如果本地 .env 有但生产没有,重新添加并 Redeploy
vercel env add DATABASE_URL
1.7 内存不足(OOM)
错误示例:
FATAL ERROR: Ineffective mark-compards near heap limit Allocation failed - JavaScript heap out of memory
修复:
# 增大 Node.js 堆内存
export NODE_OPTIONS="--max-old-space-size=4096"
npm run build
// next.config.js
module.exports = {
// 减少并发,降低内存峰值
experimental: {
workerThreads: false,
cpus: 2,
},
// 或关闭静态优化
images: {
unoptimized: true, // 如果构建卡在图片优化
},
};
1.8 构建时间过长的优化
现象:大型 Monorepo 或依赖复杂的项目构建时间超过 Vercel 限制(Hobby 45 分钟 / Pro 60 分钟),导致部署失败或排队。
原因与修复:
1. Monorepo 构建超时
# 使用 Turborepo 远程缓存,避免每次全量构建
# vercel.json
{
"buildCommand": "turbo run build --remote-cache"
}
# 在 Vercel Dashboard → Settings → Environment Variables 添加
TURBO_TOKEN=your_token
TURBO_TEAM=your_team_slug
TURBO_REMOTE_CACHE_SIGNATURE_KEY=your_signature_key
2. 依赖安装优化
# 强制使用 lock 文件,避免解析耗时
# package.json 中添加 engines
{
"packageManager": "pnpm@9.0.0",
"engines": {
"node": "20.x"
}
}
# Vercel 构建时自动使用 pnpm 的 frozen-lockfile,显著减少安装时间
# 无需额外配置,只要存在 pnpm-lock.yaml 即可
3. 增量构建策略
// next.config.js
module.exports = {
// 启用实验性增量编译(Next.js 14+)
experimental: {
incrementalCacheHandlerPath: require.resolve('./cache-handler'),
},
// 只对变更页面重新静态生成
staticPageGenerationTimeout: 120,
};
4. 构建产物过大导致上传超时
# 检查 .next 目录体积
du -sh .next/
# 如果超过 250MB(Hobby 限制),优化方向:
# 1. 将图片迁移至外部 CDN(Cloudflare R2 / AWS S3)
# 2. 禁用不必要的 Source Map
echo "NEXT_TELEMETRY_DISABLED=1" >> .env
// next.config.js
module.exports = {
productionBrowserSourceMaps: false,
images: {
remotePatterns: [
{ protocol: 'https', hostname: 'cdn.yourdomain.com' },
],
},
};
二、运行阶段故障
2.1 Serverless Functions 超时(504)
现象:页面/api 请求停顿后返回 504 GATEWAY_TIMEOUT
排查:
Vercel Dashboard → Logs → 选择 Function 执行记录
→ 查看 Duration
→ 如果超过限制(Hobby 10s / Pro 60s)→ 超时
修复策略:
// 1. 添加日志定位慢操作
export default async function handler(req: NextRequest) {
console.time('db-query');
const data = await db.query.largeTable();
console.timeEnd('db-query'); // 查看哪一步最慢
return Response.json(data);
}
// 2. 使用流式响应避免超时(AI 场景)
import { streamText } from 'ai';
export const runtime = 'edge'; // Edge 函数 30s/60s 限制比 Node.js 更灵活
const result = streamText({
model: openai('gpt-4'),
messages,
});
return result.toDataStreamResponse();
// 3. 分页/分批处理大数据
async function getLargeDataSet() {
const batchSize = 100;
let cursor = null;
const allData = [];
do {
const batch = await db.findMany({
take: batchSize,
skip: cursor ? 1 : 0,
cursor: cursor ? { id: cursor } : undefined,
});
allData.push(...batch);
cursor = batch[batch.length - 1]?.id;
} while (cursor);
return allData;
}
2.2 冷启动慢(首次访问延迟高)
现象:一段时间不访问后,首次请求耗时 1-5s
原因:Vercel Serverless Functions 在无请求时会冻结,下次请求时重新初始化(冷启动)。
缓解策略:
// 1. 用 Edge Functions(冷启动 < 5ms)替代 Node.js Functions
export const runtime = 'edge';
// 2. 在页面级别使用 ISR,让 CDN 服务缓存
export const revalidate = 3600;
// 3. 外部预热服务(如 Pingdom / UptimeRobot)每 5 分钟 ping 一次
2.3 404 路由错误
现象:
- 本地开发正常,部署到 Vercel 后某些页面 404
- App Router 和 Pages Router 同时存在时路由冲突
排查清单:
# 1. 确认文件位置正确(App Router)
ls src/app/blog/[slug]/page.tsx # ✅
ls src/app/blog/[slug].tsx # ❌ App Router 不是这样
# 2. 确认文件位置正确(Pages Router)
ls src/pages/blog/[slug].tsx # ✅
# 3. App Router + Pages Router 并存时,App Router 优先
# 如果有冲突,重命名 Pages Router 路由
// 4. 确认 generateStaticParams 返回了有效参数
export async function generateStaticParams() {
const posts = await fetchPosts();
return posts.map(p => ({ slug: p.slug }));
// 如果 posts 为空 → build 时不会生成页面
}
2.4 500 Internal Server Error
排查流程:
1. Vercel Dashboard → Logs → Functions → 筛选 500 错误
2. 查看堆栈追踪,定位出错函数和行号
3. 检查:
- 环境变量是否正确
- 数据库连接是否成功
- 外部 API 是否超时
- 是否有未捕获的 Promise 异常
// 全局错误处理
// app/error.tsx(App Router 全局错误边界)
'use client';
export default function ErrorBoundary({ error, reset }: { error: Error; reset: () => void }) {
return (
<div>
<h2>Something went wrong!</h2>
<p>{error.message}</p>
<button onClick={reset}>Try again</button>
</div>
);
}
// app/global-error.tsx(根级错误处理)
export default function GlobalError({ error, reset }: { error: Error; reset: () => void }) {
return (
<html>
<body>
<h2>Global Error</h2>
<button onClick={reset}>Reload</button>
</body>
</html>
);
}
2.5 Prisma / 数据库连接问题
现象:API 返回 500,日志显示 Connection refused 或 query timed out
排查:
# 1. 测试数据库连通性(本地)
psql "$DATABASE_URL" -c "SELECT 1"
# 2. 确认 DATABASE_URL 在 Vercel 环境变量中配置正确
# 特别注意:部分云数据库的连接 URL 有 IP 白名单限制
# 3. Prisma 连接串格式检查
# 正确:postgresql://user:password@host:5432/db?schema=public
# 错误:postgresql://user:password@host/db(缺少端口)
// 4. Prisma Client 单例模式
// lib/prisma.ts
import { PrismaClient } from '@prisma/client';
const globalForPrisma = global as unknown as { prisma: PrismaClient };
export const prisma = globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
// 5. 如果连接频繁断开,添加连接池参数
// DATABASE_URL 中添加参数:
// postgresql://...?connection_limit=5&pool_timeout=10
2.6 Edge Function 故障排查
现象:Edge Function 返回 500 或编译失败,日志提示模块缺失或体积超限。
1. Edge Runtime 与 Node.js 的兼容性问题
Edge Runtime 基于 V8 隔离环境,不支持 Node.js 原生模块:
// ❌ 以下模块在 Edge Runtime 中不可用
import fs from 'fs';
import { createServer } from 'net';
import crypto from 'crypto'; // 部分 API 缺失
// ✅ 使用 Web 标准 API 替代
// fs → 使用 fetch 从外部存储读取
// crypto → 使用 Web Crypto API
const encoder = new TextEncoder();
const data = encoder.encode('hello');
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
// ✅ 条件性导入(同一文件兼容两种 Runtime)
import { NextRequest } from 'next/server';
export const runtime = 'edge';
export async function GET(req: NextRequest) {
// 只在 Edge Runtime 中运行
const { searchParams } = new URL(req.url);
return Response.json({ ok: true });
}
2. Edge Function 代码体积超限(1MB 限制)
# 检查打包后体积
ls -la .vercel/output/functions/_func.func/index.js
# 如果 > 1MB → 需要瘦身
// next.config.js
module.exports = {
// 将重型依赖拆分为 Node.js Function
// 在路由级别指定 runtime
};
// app/api/heavy-task/route.ts
export const runtime = 'nodejs'; // 需要重型库时用 Node.js Runtime
3. Edge Function 运行时异常排查
# Edge Function 日志与 Node.js Function 日志查看方式相同
vercel logs --all | grep "edge"
# 常见异常:
# - Error: Dynamic code evaluation is not allowed → 避免 eval/new Function
# - Error: Module not found → 检查依赖是否兼容 Edge
4. Edge vs Node.js Function 的选择错误
| 场景 | 推荐 Runtime | 原因 |
|---|---|---|
| 简单 API / 中间件 / 鉴权 | Edge | 冷启动快,全球就近执行 |
| 文件系统操作 / 原生模块 | Node.js | 需要 fs/net/child_process |
| 数据库 ORM(Prisma) | Node.js | Prisma Client 需 Node.js 绑定 |
| AI 流式响应 | Edge | 支持 Streaming,延迟低 |
| 图像处理(Sharp) | Node.js | Sharp 依赖原生 libv8 |
判断方法:如果
npm ls <package>显示该包依赖nan/node-gyp/bindings,则只能在 Node.js Runtime 中使用。
三、网络与域名故障
3.1 自定义域名 404/不生效
排查清单:
# 1. DNS 是否解析到 Vercel
dig www.yourdomain.com +short
# 应该返回 cname.vercel-dns.com 或 Vercel 的 IP
# 2. SSL 证书状态
# Vercel Dashboard → Domains → 查看 SSL 状态
# 可能需要 24 小时自动签发
# 3. CNAME 是否正确
dig CNAME www.yourdomain.com +short
# 预期:cname.vercel-dns.com
3.2 SSL 证书问题
现象:浏览器提示 “不安全” / “NET::ERR_CERT_COMMON_NAME_INVALID”
修复:
- 确认域名已完全传播(DNS 传播可能需要 24-48 小时)
- Vercel Dashboard → Domains → 点击 “Refresh” 重新验证
- 如果之前用 Cloudflare → 确保 DNS 记录是 “DNS only”(灰色云朵),等 Vercel SSL 签发后再开启 Proxy
3.3 国内访问慢 / 不稳定
参照 Vercel 国内访问优化指南:
# 1. 检查默认域名是否被污染
nslookup your-project.vercel.app
# 如果返回异常 IP → 使用自定义域名
# 2. Ping 测试(从国内)
ping www.yourdomain.com
# 期望 < 100ms(如果 Cloudflare Proxy 已配置)
# 3. 检查 Cloudflare 配置
# 确保橙云代理已开启
# DNS 记录:CNAME www cname.vercel-dns.com Proxied
四、第三方集成故障
4.1 GitHub 集成断开(Webhook 失效)
现象:Push 代码后 Vercel 没有自动部署,或 PR 没有生成 Preview。
排查:
1. Vercel Dashboard → Project Settings → Git → 查看连接状态
2. GitHub → Repository → Settings → Webhooks → 查看 vercel.app webhook
→ 如果显示红色 ❌ → 点击 "Redeliver" 测试
3. 检查 GitHub App 权限:
GitHub → Settings → Applications → Vercel → Repository access
修复:
Vercel Dashboard → Project Settings → Git → Disconnect → 重新连接 GitHub Repository
# 如果 Webhook 频繁失效,检查是否因为仓库转移或改名
git remote -v
# 确认 remote URL 与 Vercel 中配置的仓库一致
4.2 OAuth 认证过期重新连接
现象:团队成员无法部署,提示权限不足;或个人账号授权过期。
修复:
1. Vercel Dashboard → Settings → Git Provider → GitHub
2. 点击 "Disconnect" → 清除浏览器缓存
3. 重新点击 "Connect" 并授权
4. 如果是 Organization 仓库 → 需要组织管理员在 GitHub 侧授权 Vercel App
4.3 Vercel Bot 评论配置
现象:GitHub PR 中没有看到 Vercel Bot 的 Preview 链接评论。
配置:
Vercel Dashboard → Project Settings → Git → Pull Request Comments
→ 勾选 "Preview URL" 和 "Build Status"
→ 如果是 Organization 项目,需要管理员权限才能修改
4.4 Teams/Organizations 权限问题
现象:团队成员看不到项目、无法部署或无法查看日志。
排查:
1. Vercel Dashboard → Settings → Members → 确认成员角色
- Owner:全部权限
- Member:可以部署和查看日志
- Viewer:只读
2. GitHub Organization → Settings → Third-party Access → Vercel
→ 确认组织已授权 Vercel
3. 如果成员通过 SSO 登录 → 检查 SAML/SCIM 配置
4.5 部署队列拥塞的处理
现象:多个 PR 同时推送时,部署排队等待时间过长,影响开发效率。
排查与优化:
# 查看当前部署队列
vercel ls
# 取消不必要的部署(如已废弃的 PR 预览)
vercel remove <deployment-url> --yes
优化策略:
1. 在 Vercel Dashboard → Settings → Git → Ignored Build Step
添加脚本跳过不影响构建的文件变更:
git diff --name-only HEAD^ HEAD | grep -v '\.md$' | grep -v '\.txt$'
2. 限制并发 Preview 部署数量:
Project Settings → Git → Pull Request → "Only build when pull requests are ready for review"
3. 使用 Pro/Enterprise 计划获取更高的并发构建配额
五、常见错误代码速查
| HTTP 状态 | 常见原因 | 修复方向 |
|---|---|---|
| 400 | 请求参数错误 | 检查 API 请求体格式 |
| 401 | 未授权 | 检查 Token/Session/Cookie |
| 403 | 禁止访问 | 检查 CORS/防火墙/IP 限制 |
| 404 | 路由不存在 | 检查文件路径、generateStaticParams |
| 405 | 方法不允许 | 检查 API Route 是否支持该 HTTP 方法 |
| 500 | 服务器内部错误 | 查看 Function Logs 堆栈 |
| 502 | 网关错误 | 上游服务(数据库/API)不可用 |
| 504 | 网关超时 | Functions 超时、数据库慢查询 |
六、Vercel 平台限制速查表
6.1 函数执行时间限制
| 计划 | Node.js Function | Edge Function |
|---|---|---|
| Hobby | 10 秒 | 30 秒 |
| Pro | 60 秒 | 30 秒 |
| Enterprise | 900 秒(15 分钟) | 30 秒 |
注意:Edge Function 无论计划均为 30 秒,但冷启动 < 5ms,更适合短响应场景。
6.2 请求与响应限制
| 限制项 | Hobby | Pro | Enterprise |
|---|---|---|---|
| 请求体大小 | 4.5 MB | 4.5 MB | 4.5 MB |
| 响应体大小 | 无限制(流式) | 无限制(流式) | 无限制(流式) |
| 并发请求 | 1000 / 区域 | 3000 / 区域 | 自定义 |
6.3 环境变量与构建限制
| 限制项 | Hobby | Pro | Enterprise |
|---|---|---|---|
| 环境变量数量 | 100 个 | 100 个 | 1000 个 |
| 单个环境变量大小 | 4 KB | 4 KB | 64 KB |
| 构建时间 | 45 分钟 | 60 分钟 | 自定义 |
| 部署频率 | 100 / 天 | 无限制 | 无限制 |
| 构建产物大小 | 250 MB | 250 MB | 500 MB |
6.4 自定义数量限制
| 限制项 | Hobby | Pro | Enterprise |
|---|---|---|---|
| 团队成员 | 无限制 | 无限制 | 无限制 |
| 项目数量 | 无限制 | 无限制 | 无限制 |
| 自定义域名 | 无限子域名 | 无限子域名 | 无限子域名 |
| Serverless Function 数量 | 12 / 部署 | 24 / 部署 | 自定义 |
超出限制时的表现:
- 构建超时 → 部署状态显示
BUILD_ERROR- 函数超时 → 浏览器返回
504 GATEWAY_TIMEOUT- 并发超限 → 新请求进入队列或返回
429 TOO_MANY_REQUESTS- 环境变量超限 → 部署时提示
ENV_VARIABLE_LIMIT_EXCEEDED
七、调试技巧
5.1 本地复现生产问题
# 1. 使用 Vercel CLI 本地运行(最接近生产环境)
npm i -g vercel
vercel dev
# 2. 带环境变量运行
vercel --prod # 部署到 production(谨慎使用)
# 3. 查看远程日志
vercel logs --all
5.2 日志查询
# Vercel CLI 查日志
vercel logs your-project.vercel.app
# 筛选特定时间段
vercel logs --since "2025-11-20T10:00:00Z"
# 只看错误
vercel logs --all | grep ERROR
5.3 Preview 环境调试
# 每个 PR 自动生成 Preview URL
# 在 PR 的 Checks 中找到 "Visit Preview" 链接
# 用 Preview 环境测试不会污染 Production
# Preview 环境使用 Preview 环境变量
八、性能优化检查清单
6.1 Core Web Vitals 优化
| 指标 | 目标 | 优化方法 |
|---|---|---|
| LCP(最大内容绘制) | < 2.5s | 图片优化、CDN 缓存、字体优化 |
| FID(首次输入延迟) | < 100ms | 减少 JS 包大小、代码分割 |
| CLS(累积布局偏移) | < 0.1 | 图片尺寸声明、字体加载策略 |
| TTFB(第一字节时间) | < 600ms | ISR/SSG、Edge Functions |
6.2 Lighthouse 优化建议
# Chrome DevTools → Lighthouse → 分析
# 常见优化点:
# 1. Image format:使用 WebP/AVIF
# 2. Lazy loading:非首屏图片延迟加载
# 3. Preconnect:添加 DNS 预解析
# 4. Font display:使用 font-display: swap
九、安全排查
7.1 环境变量泄露检查
# 1. 确保 .env 在 .gitignore 中
grep env .gitignore
# 2. 检查提交历史是否泄露过密钥
git log --all --full-history -S "sk-" # 搜索 OpenAI API Key 模式
# 3. 如果泄露,立即轮换密钥
# 并在 Vercel Dashboard 更新环境变量
7.2 CORS 配置
// app/api/cors-example/route.ts
export async function GET(request: Request) {
return new Response(JSON.stringify({ message: 'OK' }), {
headers: {
'Access-Control-Allow-Origin': 'https://yourdomain.com',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}
十、自动化监控与告警
9.1 使用 Vercel Webhooks 集成 Slack/PagerDuty
Vercel 提供部署事件 Webhook,可集成到团队通知系统:
# 1. 在 Vercel Dashboard → Project Settings → Webhooks 添加 Endpoint
# URL: https://hooks.slack.com/services/your/webhook/url
# 2. 选择事件类型:
# - deployment.succeeded
# - deployment.failed
# - deployment.canceled
// 3. 自建 Webhook 接收端(如 Next.js API Route)
// app/api/webhooks/vercel/route.ts
import { NextRequest } from 'next/server';
export async function POST(req: NextRequest) {
const payload = await req.json();
if (payload.type === 'deployment.failed') {
// 发送到 Slack / PagerDuty / 飞书
await fetch('https://hooks.slack.com/services/...', {
method: 'POST',
body: JSON.stringify({
text: `❌ 部署失败: ${payload.payload.url}\n项目: ${payload.payload.name}\n错误: ${payload.payload.error}`,
}),
});
}
return Response.json({ ok: true });
}
9.2 自定义 Uptime 监控
# 使用 Vercel Deploy Status API 检查部署状态
# 获取 Deployment ID
vercel ls --meta gitCommitRef=main
# 检查特定部署状态
curl -s "https://api.vercel.com/v13/deployments/<deployment-id>?teamId=<team>" \
-H "Authorization: Bearer $VERCEL_TOKEN" | jq '.readyState'
# 预期返回: READY / ERROR / CANCELED / BUILDING
# 结合 Cron 定期检查(可用 GitHub Actions / Vercel Cron)
# vercel.json
{
"crons": [
{
"path": "/api/health-check",
"schedule": "*/5 * * * *"
}
]
}
9.3 使用 Vercel CLI 自动化部署状态检查
#!/bin/bash
# deploy-check.sh - 在 CI/CD 中集成
DEPLOY_URL=$(vercel deploy --yes --no-wait)
echo "Deployment URL: $DEPLOY_URL"
# 等待部署完成
while true; do
STATUS=$(vercel inspect $DEPLOY_URL --timeout=1 2>/dev/null | grep "Ready" || echo "pending")
if echo "$STATUS" | grep -q "Ready"; then
echo "✅ 部署成功"
exit 0
fi
echo "⏳ 等待中..."
sleep 5
done
9.4 GitHub Actions 中集成 Vercel 部署检查
# .github/workflows/deploy-check.yml
name: Check Vercel Deployment
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: vercel/action-deploy@v1
id: vercel_deploy
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
- name: Wait for Deployment
run: |
DEPLOY_URL="${{ steps.vercel_deploy.outputs.deployment-url }}"
for i in {1..30}; do
STATUS=$(curl -s "$DEPLOY_URL/api/health" -o /dev/null -w "%{http_code}")
if [ "$STATUS" = "200" ]; then
echo "✅ 部署正常"
exit 0
fi
sleep 10
done
echo "❌ 部署检查超时"
exit 1
十一、常见问题(FAQ)
怎么看 Vercel Function 的执行时间?
Vercel Dashboard → Logs → Functions → 每行日志右侧显示 Duration。或者用 console.time / console.timeEnd 手动标记。
Vercel 支持 SSH 到服务器调试吗?
不支持。Vercel 是纯 Serverless 平台,没有持久化的服务器实例。调试依赖日志和本地复现。
部署后直接 404 怎么办?
- 检查文件是否在正确的路由目录(App Router / Pages Router)
- 检查
next.config.js是否有output: 'export'(纯静态导出不能有 API routes) - 检查是否有
vercel.json覆盖路由规则 - 确认构建产物中包含目标路由:
ls .next/server/app/
本地正常但生产报错怎么办?
- 检查环境变量差异(生产 vs 开发)
- 检查 Node.js 版本差异
- 检查
NODE_ENV影响的行为 - 检查是否有只在生产启用的中间件/功能
如何回滚到上个版本?
Vercel Dashboard → Deployments → 找到上次成功的部署 → 点击三个点 → “Promote to Production”。整个过程 1-2 秒完成。
部署卡在 Building 状态怎么处理?
现象:Dashboard 中部署状态长时间停留在 Building,超过正常构建时间。
排查:
# 1. 查看实时构建日志(可能卡在某个步骤)
vercel logs <deployment-url> --all
# 2. 常见原因:
# - 大型依赖安装(如 Sharp、Puppeteer)
# - 静态生成页数过多(上千页)
# - 外部 API 在构建时调用超时
# - 内存不足导致 Node.js GC 频繁
修复:
// 如果卡在图片优化 → 关闭静态图片优化
// next.config.js
module.exports = {
images: {
unoptimized: true,
},
};
# 如果是 Puppeteer/PhantomJS 依赖导致安装慢 → 改用外部截图服务
# 如果是静态生成页数过多 → 改用 ISR,延迟生成
Preview 环境正常但生产环境失败怎么办?
排查:
1. 确认环境变量差异:
Vercel Dashboard → Settings → Environment Variables
→ 检查 Production 和 Preview 分别配置的变量是否一致
2. 检查数据库连接:
Preview 可能连接开发数据库,Production 连接生产数据库
→ 生产数据库可能有 IP 白名单限制
3. 检查 NODE_ENV 差异:
某些库在 production 模式下行为不同(如 Prisma 的加速模式)
账单/成本突然增加怎么排查?
排查路径:
1. Vercel Dashboard → Billing → Usage
→ 查看 Function Invocations / Bandwidth / Build Minutes 哪项突增
2. 常见原因:
- 被爬虫/攻击大量请求 API → 加 Rate Limiting
- 图片未优化导致带宽暴增 → 启用 Next.js Image Optimization
- 构建频率过高(每次 commit 都触发)→ 配置 Ignored Build Step
// 添加简单的 Rate Limiting
import {NextRequest} from 'next/server';
export async function middleware(req: NextRequest) {
const ip = req.ip ?? '127.0.0.1';
const key = `rate-limit:${ip}`;
// 使用 Redis / Upstash Redis 计数
// 超过 100 次/分钟 → 返回 429
}
大文件上传失败怎么处理?
现象:API Route 接收文件上传时返回 413 Payload Too Large。
原因:Vercel Serverless Functions 请求体限制为 4.5MB(含 HTTP 头)。
解决方案:
// 1. 如果文件 < 4.5MB → 确保 Body Parser 配置正确
// app/api/upload/route.ts
export const config = {
api: {
bodyParser: {
sizeLimit: '4.5mb',
},
},
};
// 2. 如果文件 > 4.5MB → 使用预签名 URL 直传
// 客户端:请求后端生成 S3/R2 预签名 PUT URL
// 客户端:直接用 fetch PUT 上传到对象存储
// 客户端:上传完成后返回 URL 给后端保存
团队协作时部署冲突怎么处理?
现象:多个成员同时推送,后推送的覆盖了先推送的,导致功能丢失。
最佳实践:
# 1. 每个人都通过 PR 部署,禁止直接 push 到 main
git branch feature/my-feature
git push origin feature/my-feature
# 在 GitHub 发起 PR,通过 Preview 验证后再合并
2. 合并策略:
GitHub → Settings → Branches → main → Branch protection rules
→ Require pull request reviews before merging
→ Require status checks to pass(Vercel Build + 你的测试)
3. 如果冲突已发生:
Vercel Dashboard → Deployments → 找到正确版本的部署 → Promote to Production
十二、故障排查工具箱
10.1 浏览器 Network 面板的高级用法
1. 查看请求是否命中 Vercel Edge Network:
Network → 点击请求 → Response Headers → x-vercel-cache
值:HIT(CDN 缓存)/ MISS(回源)/ STALE(缓存过期)/ BYPASS(跳过缓存)
2. 查看 Function 执行信息:
x-vercel-id: sfo1::iad1-1234567890abcdef
↑
请求处理区域(如 sfo1 = San Francisco)
3. 检查缓存策略:
Cache-Control: s-maxage=3600, stale-while-revalidate=86400
→ ISR 的缓存头,3600 秒后重新生成
10.2 curl 命令测试 Vercel 部署
# 基础请求测试
curl -I https://your-project.vercel.app/
# 测试缓存行为
curl -I -H "Cache-Control: no-cache" https://your-project.vercel.app/
# 测试不同区域(通过 VPN 或 Cloudflare Worker)
# 检查 x-vercel-id 中的区域代码
# 测试 API 超时阈值
curl -w "@curl-format.txt" -o /dev/null -s https://your-project.vercel.app/api/slow-endpoint
# curl-format.txt 内容:
# time_namelookup: %{time_namelookup}\n
# time_connect: %{time_connect}\n
# time_total: %{time_total}\n
10.3 Vercel CLI 命令详解
# 查看实时日志(按项目)
vercel logs <project-url> --all --follow
# 查看特定函数的日志
vercel logs <project-url> --all | grep "/api/users"
# 查看部署详情(包含构建时间、环境变量等)
vercel inspect <deployment-url>
# 列出环境变量
vercel env ls
# 添加环境变量(交互式)
vercel env add DATABASE_URL
# 导出环境变量到本地
echo $(vercel env ls | grep DATABASE_URL | awk '{print $2}')
# 查看部署历史
vercel ls --meta gitCommitRef=feature/my-branch
# 回滚到某个部署
vercel --version <deployment-url>
10.4 第三方工具推荐组合
| 工具 | 用途 | 与 Vercel 的集成方式 |
|---|---|---|
| Sentry | 错误追踪与性能监控 | @sentry/nextjs 自动捕获 500 错误和慢查询 |
| Logflare | 结构化日志存储与分析 | Vercel Integration → Logflare,转发所有 Function Logs |
| UptimeRobot | 外部可用性监控 | 设置每 5 分钟 ping 关键页面,Vercel 冷启动自动预热 |
| Inngest | 后台任务队列(替代长时 Function) | 通过 Webhook 触发,Vercel Function 只做入队 |
| Upstash Redis | 状态共享与限流 | Edge-compatible,支持 Rate Limiting 和 Session 存储 |
相关阅读
- Vercel 详解:前端与 AI 应用的一站式云平台
- Vercel 国内访问优化指南
- Vercel 定价与成本详解
- Vercel Edge Functions 深度指南
- Vercel Middleware 实战指南
- Vercel ISR 完整指南
- Vercel 部署 Nuxt.js (Vue) 实战
- Vercel 专题导航
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。