前置阅读:建议先阅读 Vercel Edge Functions 深度指南 了解 Edge Runtime 基础知识。
关键概念:Edge Config 是 Vercel 提供的全局键值存储,数据部署到全球 Edge Network,读取延迟 < 5ms,写入后 10 秒内全球同步,专为配置管理、功能开关和 A/B 测试场景设计。
² 核心特性与适用场景
特性 规格 说明 读取延迟 < 5ms (p99) 数据缓存在 Edge Network 节点 写入同步 ~10s 全球传播 异步最终一致 单条记录上限 8 KB 适合配置和开关,不适合大体积数据 单 Store 记录数 10,000 条(Pro) 按 tier 递增 读取配额 500K reads/mo(Hobby) Pro 50M/mo 最佳场景:
- 🚦 功能开关(Feature Flags)— 无需重新部署即可控制功能上线
- 🧪 A/B 测试 — 基于用户属性分流
- 🌍 维护模式 — 一键切换 “系统维护中” 页面
- 💰 动态定价 — 实时调整费率或促销配置
不适用于:用户会话存储(写少读多但写延迟不可控)、大文件缓存、需要强一致性的事务。
³ 基础操作与数据结构
# 安装 CLI 工具 npm i -g vercel # 创建 Edge Config Store vercel edge-config create my-app-config # 设置键值(支持 JSON 值) vercel edge-config set my-app-config FEATURE_DARK_MODE=true vercel edge-config set my-app-config PRICING_V2='{"enabled":true,"percentage":25}' # 读取 vercel edge-config get my-app-config FEATURE_DARK_MODE # 批量导入 vercel edge-config import my-app-config ./flags.json# flags.json { "features": { "new_checkout": { "enabled": true, "rollout_percentage": 10, "target_regions": ["us-east-1", "eu-west-1"] }, "beta_search": { "enabled": false, "allowed_user_ids": ["user_123", "user_456"] } }, "maintenance": { "active": false, "message": "Scheduled maintenance at 02:00 UTC" } }⁴ Edge Functions 中读取
// app/api/flags/route.ts import { get } from "@vercel/edge-config"; export const runtime = "edge"; export async function GET() { // 单次读取:< 5ms const features = await get("features"); const maintenance = await get("maintenance"); return Response.json({ features, maintenance, timestamp: Date.now(), }); }// 批量读取(减少网络往返) import { getAll } from "@vercel/edge-config"; export async function GET() { // 一次获取多个 key const { features, maintenance, pricing } = await getAll([ "features", "maintenance", "pricing", ]); return Response.json({ features, maintenance, pricing }); }⁵ Middleware 中实现 Feature Flags
// middleware.ts import { NextResponse } from "next/server"; import { get } from "@vercel/edge-config"; import type { NextRequest } from "next/server"; export const config = { matcher: ["/checkout/:path*", "/dashboard/:path*"], }; export async function middleware(request: NextRequest) { const features = await get<FeatureFlags>("features"); // 1. 维护模式检查(最高优先级) const maintenance = await get<MaintenanceConfig>("maintenance"); if (maintenance?.active) { return NextResponse.rewrite(new URL("/maintenance", request.url)); } // 2. 功能开关路由重写 if (request.nextUrl.pathname.startsWith("/checkout")) { const checkoutFlag = features?.new_checkout; if (checkoutFlag?.enabled) { // A/B 测试:按用户 ID hash 分流 const userId = request.cookies.get("user_id")?.value; const isInRollout = userId ? hashToPercentage(userId) < (checkoutFlag.rollout_percentage || 0) : false; if (isInRollout) { // 重写到新版结账页 return NextResponse.rewrite( new URL("/checkout/v2" + request.nextUrl.pathname.replace("/checkout", ""), request.url) ); } } } return NextResponse.next(); } // 简单哈希函数:将字符串转为 0-100 的百分比 function hashToPercentage(str: string): number { let hash = 0; for (let i = 0; i < str.length; i++) { hash = ((hash << 5) - hash + str.charCodeAt(i)) | 0; } return Math.abs(hash) % 100; }⁶ A/B 测试完整实现
// lib/ab-test.ts import { get } from "@vercel/edge-config"; interface ABTestConfig { enabled: boolean; variants: Array<{ id: string; weight: number; // 0-1 target?: { region?: string[]; device?: ("mobile" | "desktop")[]; }; }>; } export async function assignVariant( experimentId: string, userId: string, context: { region?: string; device?: string } ): Promise<string | null> { const config = await get<ABTestConfig>(`ab_${experimentId}`); if (!config?.enabled) return null; // 按目标过滤 const eligible = config.variants.filter(v => { if (v.target?.region && !v.target.region.includes(context.region || "")) return false; if (v.target?.device && !v.target.device.includes(context.device as any)) return false; return true; }); // 一致性哈希:同一用户始终分配到同一 variant const hash = hashToPercentage(`${experimentId}:${userId}`); let cumulative = 0; for (const variant of eligible) { cumulative += variant.weight; if (hash < cumulative * 100) return variant.id; } return eligible[0]?.id || null; } // 在 Edge Function 中使用 export async function GET(request: Request) { const userId = request.headers.get("x-user-id") || "anonymous"; const variant = await assignVariant("homepage_redesign", userId, { region: request.headers.get("x-vercel-ip-country") || "", device: "desktop", }); if (variant === "v2") { return fetch("https://cdn.example.com/homepage-v2.html"); } return fetch("https://cdn.example.com/homepage.html"); }⁷ 版本控制与回滚
Edge Config 本身没有原生版本控制,需要通过外部方案实现:
// lib/edge-config-versioned.ts import { createClient } from "@vercel/edge-config"; const client = createClient( process.env.EDGE_CONFIG, { cache: "no-store" } // 跳过缓存,始终读取最新 ); // 方案:配置变更时写入带版本号的 key async function setVersionedConfig(key: string, value: any) { const version = Date.now(); await client.set(`${key}:v${version}`, JSON.stringify(value)); await client.set(`${key}:current`, version.toString()); } async function getVersionedConfig(key: string, version?: string) { const targetVersion = version || (await client.get(`${key}:current`)); return client.get(`${key}:v${targetVersion}`); } // 回滚:只需将 current 指向前一个版本 async function rollback(key: string) { // 获取版本列表并回退 // 实际实现需要在外部(如 Redis / 数据库)维护版本索引 }推荐方案:将 Edge Config 作为热缓存层,配置源放在 Git(版本控制)或数据库中,通过 CI/CD 或管理后台同步到 Edge Config。
⁸ 与专业 Feature Flags 服务对比
维度 Vercel Edge Config LaunchDarkly Unleash Flagsmith 读取延迟 < 5ms ~50-100ms ~20-50ms ~30-80ms SDK 复杂度 极简(单函数) 中等 中等 中等 A/B 测试 需自建 原生支持 原生支持 原生支持 分析与归因 无 完整 基础 基础 规则引擎 简单 JSON 复杂规则集 中等 中等 成本(起始) 含在 Vercel 套餐 $10/席位/mo 开源(自托管) 开源/托管 适合场景 Vercel + 简单开关 企业级全功能 自托管偏好 开源预算敏感 推荐:如果全栈在 Vercel,且需求是简单的功能开关和维护模式,Edge Config 足够;如果需要复杂 A/B 测试和用户分析,搭配 LaunchDarkly SDK 在客户端实现。
延伸阅读:
- Vercel Edge Functions 深度指南 — Edge Runtime 架构与流式响应
- Vercel Middleware 实战指南 — 路由拦截、认证与灰度发布
- Vercel 部署 Next.js + Postgres SaaS 实战 — 全栈 SaaS 中的动态配置管理
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。
「工具与平台」更多文章
Vercel Analytics 深度指南:Web Vitals 监控、真实用户性能与转化归因
全面解析 Vercel Analytics(真实用户监控 RUM)与 Speed Insights(Web Vitals)两大工具,覆盖安装集成、自定义事件追踪、性能瓶颈诊断、转化归因分析,以及与 Google Analytics 4 / Datadog 的对比选型。
Vercel AI SDK 深度实战:Tool Calling、Schema 流式输出与多模型路由
深入 Vercel AI SDK 三大核心包(ai / @ai-sdk/openai / @ai-sdk/react),覆盖 generateObject 结构化输出、streamText 工具调用流、多模型路由与回退、Server Action 集成等高级场景,提供端到端 TypeScript 实现。
Cloudflare Workers AI 高级实战:自定义模型部署、批量推理与 AI Gateway 缓存策略
深入 Cloudflare Workers AI 生产级应用:Workers AI Catalog 模型量化原理、批量推理优化、AI Gateway 多级缓存与智能限流、自定义模型 Workers AI 部署(TensorFlow.js / ONNX Runtime),含完整 TypeScript 实现与成本基准。