1. CDN 工作机制
CDN(Content Delivery Network,内容分发网络)通过在全球部署边缘节点,将静态资源缓存到离用户最近的位置,从而大幅降低延迟、节省回源带宽。用户使用 CDN 时,DNS 解析返回的是最近的 POP(Point of Presence,接入点)节点的 IP,用户的 HTTP 请求直接由边缘节点响应。
典型的请求链路如下:
- 用户请求
https://example.com/image.jpg。 - DNS 通过 Anycast 返回距离用户最近的边缘节点 A。
- 节点 A 检查本地缓存:命中则直接返回;未命中则回源到源站拉取,并缓存到本地。
- 响应返回给用户,同时缓存频繁访问的资源以供后续请求复用。
边缘节点分层组织,通常包含边缘层(L1)和父节点层(L2)。L1 节点直接面向用户,miss 时向 L2 节点回源;L2 节点再向源站或对象存储回源。两级缓存结构有效减少源站压力。
2. 缓存策略与优化
缓存是 CDN 的核心能力。合理的缓存策略能提升命中率、降低回源流量,而不当的配置可能导致用户看到过期内容。
2.1 TTL 与 Cache-Control
TTL(Time to Live)决定资源在边缘节点缓存的时长。Web 服务器应通过响应头明确声明缓存规则:
Cache-Control: public, max-age=86400, immutable
ETag: "abc123"
Last-Modified: Wed, 01 Sep 2026 08:00:00 GMT
Vary: Accept-Encoding
上述头部表示该资源允许公开缓存 24 小时,immutable 标记表明 URL 对应的文件内容永不更改,浏览器和 CDN 都可以放心长期缓存。Vary: Accept-Encoding 确保按压缩类型分别缓存。
对于静态文件,推荐采用文件指纹命名(如 main.a3f7c.js),配合永久缓存策略:
Cache-Control: public, max-age=31536000, immutable
2.2 命中与回源控制
缓存命中率(Cache-Hit Ratio)是 CDN 的核心指标。提升命中率的方法包括:
- 归一化 URL:统一大小写、忽略无关查询参数(如 UTM 标记),防止同一资源产生多个缓存键。
- 忽略 Cookie:静态资源不需要会话状态,配置
Cache-Control: public并阻止 Cookie 影响缓存键。 - 预取(Prefetch):在页面中通过
<link rel="prefetch">或推送关键资源到边缘节点。
2.3 缓存刷新
当内容更新时,三种方式刷新 CDN 缓存:
- TTL 自然过期:等待缓存到期,适合更新不敏感场景。
- 主动清洗(Purge):调用 API 或控制面板按 URL、Tag 或全站清除缓存,生效时间从秒级到分钟级不等。
- 版本化 URL:修改文件名中的 hash,旧缓存自然失效,这是最稳妥的更新方式。
2.4 Stale-While-Revalidate
现代浏览器和高级 CDN(如 Cloudflare、Fastly)支持 stale-while-revalidate:
Cache-Control: public, max-age=60, stale-while-revalidate=86400
头部含义为:资源在 CDN 和浏览器中最多缓存 60 秒并在 60~86400 秒内仍可淡旧提供(stale),同时后台异步回源刷新。该模式兼顾新鲜度与性能,适合非交易类动态内容。
3. Anycast 与智能路由
Anycast 是一种 BGP 路由技术,同一组 IP 从多个地理分散的 POP 节点同时宣告。用户请求路由到其 ISP 的路由表中距离最短的节点,实现就近接入。
[User in Tokyo]
|
[ISP/BGP Routing]
/ \
[POP Tokyo] [POP Singapore]
| |
[最佳路径 ← 最短 AS-PATH]
Anycast 的天然优势:
- 就近接入:自动选择延迟最低的 POP,无需复杂的客户端调度。
- DDoS 吸收:分布式布局将攻击流量分散到多个边缘节点,单一节点压力骤减。
- 故障转移:某个 POP 下线时,BGP 路由自动收敛,用户请求切换到下一最优节点。
4. 边缘计算(Edge Computing)
传统 CDN 只缓存静态内容,而边缘计算允许在 POP 节点上执行轻量代码逻辑,将计算推向用户侧。
4.1 Cloudflare Workers
Cloudflare Workers 运行在 V8 Isolate 上,启动时间接近零,适合边缘路由、A/B 测试、身份验证等场景:
// worker.js — Cloudflare Workers 示例
export default {
async fetch(request, env) {
const url = new URL(request.url);
// A/B 测试拆分
const cookie = request.headers.get('Cookie') || '';
let variant = cookie.includes('variant=B') ? 'B' : 'A';
if (!cookie.includes('variant=')) {
variant = Math.random() < 0.5 ? 'A' : 'B';
}
const response = await fetch(`https://origin.example.com${url.pathname}?v=${variant}`, {
cf: { cacheTtl: 300, cacheEverything: true },
});
const newResponse = new Response(response.body, response);
newResponse.headers.set('Set-Cookie', `variant=${variant}; Path=/; HttpOnly`);
return newResponse;
},
};
4.2 Vercel Edge Functions 与 Lambda@Edge
- Vercel Edge Functions:基于 V8,与 Next.js 深度集成,适合国际化路由、边缘渲染。
- AWS Lambda@Edge:运行在 CloudFront 边缘节点,支持 Node.js 和 Python,但冷启动比 Workers 略高。
三者的选择依据取决于现有基础设施:已有 Cloudflare 生态选 Workers,已有 AWS 选 Lambda@Edge,Next.js 项目优先 Vercel。
5. CDN 加速动态内容
API 响应和动态页面难以长期缓存,但借助恰当的头部和时间窗口,仍可利用 CDN 提升响应速度与稳定性。
5.1 API 缓存策略
对于读多写少的 API,设置短 TTL 配合 stale-while-revalidate:
Cache-Control: public, max-age=10, stale-while-revalidate=60
结合 ETag 实现条件请求,当源站数据未变时返回 304 Not Modified,节省传输带宽:
GET /api/prices HTTP/1.1
If-None-Match: "etag-abc123"
HTTP/1.1 304 Not Modified
5.2 动态加速(Dynamic Site Acceleration, DSA)
对于不可缓存的动态请求,传统 CDN 仍提供 TCP 优化:
- TCP 连接复用:边缘节点与源站保持长连接池,减少握手开销。
- TLS 1.3 0-RTT:边缘到用户的握手加速。
- 路由优化:CDN 专用骨干网链路绕过拥堵公网。
# 边缘到源站的连接优化
Connection: keep-alive
Keep-Alive: timeout=60, max=1000
6. 全球多区域部署与故障转移
面向全球用户的系统应采用多区域源站配合 CDN 使用:
[User]
|
[CDN Edge POP]
|
+----+--------------------+
| |
[Origin: us-east] [Origin: ap-southeast]
(主) (备/区域)
部署模式:
- 单 CDN + 多源:CDN 按地理位置将回源路由到最近的源,可通过健康检查自动故障转移。
- 多云 CDN:同时使用 Cloudflare + AWS CloudFront,通过 DNS 分区或主备策略实现冗余。
- 源站屏蔽:源站仅接受 CDN 回源的白名单 IP,避免直接暴露。
Cloudflare Health Check 配置示例:
# Cloudflare Load Balancing 示例
origin_pools:
- name: us-east
origins:
- address: origin-us.example.com
weight: 100
monitor:
type: http
path: /health
interval: 60
timeout: 5
- name: ap-southeast
origins:
- address: origin-sg.example.com
weight: 100
monitor:
type: http
path: /health
interval: 60
timeout: 5
steering_policy: geo
7. 性能对比
部署 CDN 前后延迟差异显著:
| 场景 | 未使用 CDN | 使用 CDN | 提升 |
|---|---|---|---|
| 静态资源(东京用户访问纽约源站) | 280 ms | 25 ms | ~90% |
| 首字节时间(TTFB) | 450 ms | 85 ms | ~81% |
| 全球平均 DNS 解析 | 120 ms | 15 ms | ~87% |
| 回源带宽消耗 | 100% | ~8% | ~92% |
CDN 的价值不仅在于减少延迟峰值,还在于高并发时的流量承载和 DDoS 防护——边缘节点吸收了绝大多数请求,源站仅在缓存未命中时介入。
8. 基于 Cloudflare 的实战配置
以下是一份典型网站的 Cloudflare 完整配置参考。
8.1 DNS 设置
将域名 DNS 托管到 Cloudflare,启用代理(橙色云)功能:
Type: A
Name: www
Content: 1.2.3.4(源站 IP)
Proxy status: Proxied
TTL: Auto
8.2 Page Rules
利用 Page Rules 为不同路径设置差异化策略:
URL: *example.com/static/*
Settings:
- Cache Level: Cache Everything
- Edge Cache TTL: 1 month
- Browser Cache TTL: 1 month
- Always Online: On
URL: *example.com/api/*
Settings:
- Cache Level: Bypass(或设置短 TTL)
- Origin Cache Control: On
8.3 Workers 路由与 KV 缓存
使用 Cloudflare Workers 和 KV 构建边缘配置缓存:
// workers/config-cache.js
export default {
async fetch(request, env, ctx) {
const cacheKey = 'config:v2';
let data = await env.KV_CACHE.get(cacheKey, { type: 'json' });
if (!data) {
const resp = await fetch('https://origin.example.com/api/config');
data = await resp.json();
// 缓存到 KV,TTL 5 分钟
await env.KV_CACHE.put(cacheKey, JSON.stringify(data), { expirationTtl: 300 });
}
return new Response(JSON.stringify(data), {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'public, max-age=60',
},
});
},
};
8.4 Analytics 监控
Cloudflare Analytics 面板提供以下核心指标:
- Edge Cache Hit Ratio:低于 90% 时检查 URL 归一化和 TTL 配置。
- Bandwidth Saved:展示回源节省的百分比。
- Security Events:WAF 拦截、Bot 管理、DDoS 攻击日志。
- Core Web Vitals:从边缘视角收集的 LCP / FID / CLS 数据。
配合 cf-cache-status 响应头排查命中状态:
HTTP/1.1 200 OK
cf-cache-status: HIT | MISS | EXPIRED | DYNAMIC
总结
CDN 不仅是静态资源的加速层,更是现代互联网架构的基础设施。从缓存策略到 Anycast 路由,从边缘计算到全球多源部署,每一个环节都能显著影响用户体验和系统韧性。选型上,中小型项目可从 Cloudflare 免费层起步,逐步按需引入 Workers 和 Load Balancing;大型企业则需在多云 CDN 之间做冗余,结合监控与自动故障转移构建高可用的全球内容分发体系。
参考链接
- RFC 7234 - HTTP Caching
- Cloudflare Cache Docs
- AWS CloudFront Developer Guide
- Anycast and BGP Best Practices
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。