Edge Runtime 与 Serverless Runtime

323 阅读3分钟

一、基本定义

类型定义
Serverless Runtime指在云服务(如 AWS Lambda)上运行的无状态函数,按请求触发,运行在**中心化服务器(Region)**中。
Edge Runtime指代码运行在**CDN 边缘节点(Edge Node)**的沙箱环境中,靠近用户,延迟更低,使用 Web 标准 API 执行。

二、底层运行原理对比

特性Serverless RuntimeEdge Runtime
运行环境Node.js、支持 CommonJS/ESM基于 V8 引擎(非 Node.js),无 Node 核心模块
执行位置云 Region 中心服务器(如 AWS us-east-1)离用户最近的 CDN 边缘节点(如东京、新加坡)
触发方式按请求启动(有冷启动)按请求启动(极低冷启动)
资源限制内存大、运行时间长内存小、执行时间短
支持 APINode.js API 全支持,如 fshttpcrypto仅支持 Web 标准 API,如 fetchRequestResponse
文件系统访问✅ 支持❌ 不支持
数据库连接✅ 支持直连 MySQL/MongoDB 等⚠️ 不推荐(无 TCP 支持、无连接池)

三、启动与响应性能对比

对比项ServerlessEdge
启动时间50ms ~ 800ms(冷启动)<10ms(近似无冷启动)
运行时长限制通常几分钟(如 AWS Lambda 最长 15 分钟)通常几秒(如 Cloudflare Worker 最多 30 秒)
并发能力支持高并发(自动扩展)支持极高并发(且无需冷启动)
本地模拟支持✅ 可用 next dev 本地模拟⚠️ 本地模拟困难、需平台支持(如 Vercel CLI)

四、应用场景对比

场景类型Serverless RuntimeEdge Runtime
SSR 页面渲染✅ 推荐,支持数据库、缓存等复杂逻辑⚠️ 不推荐,因不支持数据库直连
国际化重定向✅ 可做,但慢✅ 非常推荐,极快
登录鉴权✅ 推荐✅ 推荐(如 JWT 验证)
A/B 实验✅ 推荐✅ 推荐(执行速度快)
数据库操作✅ 推荐❌ 不推荐
静态资源预处理❌ 无意义✅ 可拦截 CDN 请求处理逻辑
CDN 边缘响应 API❌ 慢✅ 最佳选择
页面 Layout Server Components(App Router)✅ 支持✅ 支持,需 export const runtime = 'edge'

五、Next.js 中的使用方式

1. Serverless(默认)

适用于任何 API 路由、SSR 页面:

// 默认 Node.js Runtime
export async function GET(req: Request) {
  // 可以连接数据库、使用 fs、进行 SSR 等
}

2. Edge Runtime

middleware.ts、API 路由或 page.tsx 中启用:

export const runtime = 'edge';

export async function GET() {
  return new Response('Hello from Edge!');
}

六、与平台的关系

平台Serverless RuntimeEdge Runtime
Vercel✅ 默认支持✅ 强力支持(推荐平台)
Cloudflare Workers❌ 不支持✅ 支持(原生)
Netlify Functions✅ 支持✅ 支持(部分)
AWS Lambda✅ 支持✅ 需使用 Lambda@Edge
阿里云函数计算✅ 支持⚠️ 支持有限
自建 Node.js 服务✅ 支持❌ 不支持 Edge

七、优缺点总结

✅ Serverless Runtime 优势

  • 支持数据库连接、文件操作

  • 更强的计算能力和执行时长

  • 更灵活,调试方便

❌ Serverless Runtime 缺点

  • 冷启动慢(尤其是首次)
  • 距离用户远,延迟高
  • 无法处理 CDN 级别请求

✅ Edge Runtime 优势

  • 毫秒级冷启动
  • 离用户更近,延迟极低
  • 非常适合轻量请求、前置逻辑、边缘缓存判断

❌ Edge Runtime 缺点

  • 无法访问 Node 核心模块
  • 无法直连数据库
  • 无文件系统、不适合重计算任务

总结建议

场景推荐运行时
页面 SSR + 数据库渲染✅ Serverless
登录状态校验 / token 验证✅ Edge
CDN 边缘路由拦截(如国际化)✅ Edge
复杂 API 接口处理✅ Serverless
页面 Layout 的快速响应组件✅ Edge(App Router)

实战例子

登录校验(middleware.ts + Edge)

export function middleware(request) {
  const token = request.cookies.get('token')
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
  return NextResponse.next()
}

国际化跳转

export function middleware(req) {
  const lang = req.headers.get('accept-language')
  const url = req.nextUrl
  if (!url.pathname.startsWith('/zh')) {
    url.pathname = '/zh' + url.pathname
    return NextResponse.redirect(url)
  }
}