边缘限流
用边缘限流(令牌桶或滑动窗口)保护 API 免遭滥用。
边缘高级
为什么
边缘限流在到达源站前阻止滥用,节省计算和数据库成本。Cloudflare 边缘网络覆盖 330+ 城市,全球 p95 延迟低于 50ms。
边缘函数相比源服务器将 TTFB 降低 60-80%,Akamai 报告 2024 年 40% 的企业使用边缘计算。
何时使用
公共 API、登录端点或任何易受暴力/爬取的资源。 需要数据库写入的有状态逻辑避免边缘函数 — 边缘运行时无持久连接池。需要长时间运行任务(>30s)或重 CPU 计算时跳过。
如何做
# Vercel 边缘 配置 + 速率限制ing
import { get } from '@vercel/edge-config';
export default async function handler(req: Request) {
const ip = req.headers.get('x-forwarded-for') || 'unknown';
const key = `ratelimit:${ip}`;
const count = parseInt(await get(key) || '0');
if (count >= 100) {
return new Response('Too Many Requests', {
status: 429,
headers: { 'Retry-After': '60' }
});
}
// Increment counter (use Upstash Redis for atomic)
await fetch(`https://api.upstash.com/redis/incr/${key}`);
return handler(req);
}
4. 验证部署 — curl -I https://your-app.example.com
5. 监控日志 — 前 5 分钟检查错误
6. 需要时回滚 — 回退到上一版本
示例
# Cloudflare Workers 速率限制ing
export default {
async fetch(req, env) {
const ip = req.headers.get('cf-connecting-ip');
const { pathname } = new URL(req.url);
const rule = {
pathname: '/api/*',
limit: 100,
period: 60,
};
const count = await env.RATE_LIMIT.get(ip) || 0;
if (count >= rule.limit) {
return new Response('Rate limited', { status: 429 });
}
return fetch(req);
}
};
常见问题
- ⚠限流过严 — 根据合法流量模式调整
- ⚠分布式请求绕过限制 — 用 IP + 用户 ID 复合 key
- ⚠环境间配置漂移 — 使用基础设施即代码(Terraform/Pulumi)保持 dev/staging/prod 一致
最佳实践
- ✓用 429 带 Retry-After — 客户端可优雅重试
- ✓用滑动窗口 — 比固定窗口更平滑
- ✓设置健康检查和优雅关闭 — 处理 SIGTERM 以在退出前排空进行中的请求