CDN架构设计Skill cdn-architecture

该技能专注于内容交付网络(CDN)的架构设计与优化,包括缓存策略、边缘计算、性能提升和源站管理,适用于Web应用开发、云计算环境和全球内容分布,关键词:CDN,缓存,边缘优化,内容交付,性能优化,云原生。

云原生架构 0 次安装 0 次浏览 更新于 3/11/2026

名称: cdn-architecture 描述: 用于设计内容交付网络、缓存策略或全球内容分布时使用。涵盖CDN架构、缓存层次结构、源站屏蔽、缓存失效和边缘优化。 允许工具: Read, Glob, Grep

CDN架构

内容交付网络架构的综合指南 - 缓存、分布和边缘优化模式。

何时使用此技能

  • 为Web应用程序设计CDN策略
  • 实施缓存层次结构
  • 优化源站负载和性能
  • 理解缓存失效模式
  • 选择CDN提供商和功能
  • 配置边缘缓存规则

CDN基础

CDN如何工作

无CDN:
用户(东京) ───────────────────► 源站(纽约)
              2000公里,~200毫秒RTT

有CDN:
用户(东京) ──► 边缘(东京) ──► 源站(纽约)
              <10公里,~10毫秒RTT    (仅在缓存未命中时)

CDN好处:
├── 减少延迟(内容从附近提供)
├── 源站卸载(较少请求击中源站)
├── DDoS防护(分布式,吸收攻击)
├── 可扩展性(处理流量峰值)
└── 可靠性(多个POP提供冗余)

CDN架构

CDN组件:

┌─────────────────────────────────────────────────────────┐
│                     互联网                             │
└────────────────────────┬────────────────────────────────┘
                         │
         ┌───────────────┼───────────────┐
         │               │               │
    ┌────▼────┐    ┌────▼────┐    ┌────▼────┐
    │  边缘   │    │  边缘   │    │  边缘   │
    │ POP 1   │    │ POP 2   │    │ POP 3   │
    │(东京)  │    │(伦敦) │    │(纽约)  │
    └────┬────┘    └────┬────┘    └────┬────┘
         │               │               │
         └───────────────┼───────────────┘
                         │
              ┌──────────▼──────────┐
              │    源站屏蔽         │
              │    (中间层)       │
              └──────────┬──────────┘
                         │
              ┌──────────▼──────────┐
              │       源站          │
              │    (您的服务器)   │
              └─────────────────────┘

术语:
- POP:存在点(边缘位置)
- 边缘:最接近用户的服务器
- 源站屏蔽:可选中间缓存
- 源站:您的实际服务器

缓存命中/未命中流程

请求流程:

1. 用户请求asset.js

2. 边缘缓存检查
   ┌─────────────────────────────┐
   │ asset.js在边缘缓存中吗?     │
   └─────────────┬───────────────┘
                 │
        ┌────────┴────────┐
        │                 │
   命中:立即返回        未命中:转发
   (~10毫秒)           到源站屏蔽

3. 源站屏蔽检查(如配置)
   ┌─────────────────────────────┐
   │ asset.js在屏蔽中吗?        │
   └─────────────┬───────────────┘
                 │
        ┌────────┴────────┐
        │                 │
   命中:返回到边缘       未命中:转发
   (~50毫秒)            到源站

4. 源站获取
   ┌─────────────────────────────┐
   │ 从源站服务器获取           │
   │ 在屏蔽和边缘中缓存         │
   └─────────────────────────────┘
   (~200毫秒)

关键指标:
- 缓存命中率(CHR):从缓存服务的请求百分比
- 首字节时间(TTFB):接收首字节的延迟
- 源站请求:到达源站的请求数量

缓存策略

Cache-Control头部

Cache-Control指令:

浏览器 + CDN:
Cache-Control: public, max-age=31536000
└── 任何人可缓存1年

仅CDN:
Cache-Control: private, no-store
└── 不缓存(敏感数据)

短期缓存:
Cache-Control: public, max-age=300, s-maxage=3600
└── 浏览器:5分钟,CDN:1小时

陈旧-while-重新验证:
Cache-Control: public, max-age=3600, stale-while-revalidate=86400
└── 在后台重新验证时提供陈旧内容24小时

CDN特定头部:
CDN-Cache-Control: max-age=3600
Surrogate-Control: max-age=3600
Cloudflare-CDN-Cache-Control: max-age=3600

缓存决策矩阵

内容类型 → 缓存策略:

静态资源(JS, CSS, 图像):
├── 长TTL(1年)
├── 基于内容的文件名(哈希)
├── 不可变标志
└── Cache-Control: public, max-age=31536000, immutable

HTML页面:
├── 短TTL或无缓存
├── 基于重新验证
├── ETag/最后修改
└── Cache-Control: no-cache(每次重新验证)

API响应(公共数据):
├── 短到中TTL
├── 根据适当头部变化
├── 考虑stale-while-revalidate
└── Cache-Control: public, max-age=60, stale-while-revalidate=300

API响应(个性化):
├── 不在CDN缓存
├── 可在浏览器缓存带认证
└── Cache-Control: private, no-store

用户生成内容:
├── 中TTL
├── 更新时考虑清除
└── Cache-Control: public, max-age=3600

Vary头部

Vary头部用法:

目的:基于请求头部缓存不同版本

Vary: Accept-Encoding
└── 缓存单独的gzip、brotli和普通版本

Vary: Accept-Language
└── 按语言缓存单独版本
└── 警告:可能导致缓存变体爆炸

Vary: Cookie
└── 通常意味着“不在CDN缓存”
└── 每个唯一cookie = 不同缓存条目

最佳实践:
✓ Vary: Accept-Encoding(始终用于可压缩内容)
✓ Vary: Origin(用于CORS)
✗ 避免Vary: Cookie(缓存片段化严重)
✗ 避免Vary: User-Agent(数千变体)

Vary替代方案:
- 在边缘规范化头部
- 使用查询参数替代
- 为不同变体使用单独URL

源站屏蔽

屏蔽架构

无源站屏蔽:

边缘POPs:200+位置
    │ │ │ │ │ │ │ │ │ │
    └─┴─┴─┴─┴─┴─┴─┴─┴─┘
              │
    所有200个POPs可从源站请求
              ▼
         ┌────────┐
         │  源站  │  (200个潜在请求者,在缓存未命中时)
         └────────┘

有源站屏蔽:

边缘POPs:200+位置
    │ │ │ │ │ │ │ │ │ │
    └─┴─┴─┴─┴─┴─┴─┴─┴─┘
              │
    所有边缘未命中转到屏蔽
              ▼
    ┌─────────────────┐
    │   源站屏蔽      │  (每个区域1个屏蔽)
    │   (合并)      │
    └────────┬────────┘
             │
    仅屏蔽从源站请求
             ▼
         ┌────────┐
         │  源站  │  (1-3个潜在请求者)
         └────────┘

好处:
- 合并缓存未命中
- 减少源站负载
- 更好的缓存效率
- 改进源站可用性

请求合并

请求合并(汇聚):

场景:100个用户同时请求相同未缓存资源

无合并:
100个请求 ──► 边缘 ──► 100个请求 ──► 源站
                         (雷群效应)

有合并:
100个请求 ──► 边缘 ──► 1个请求 ──► 源站
                  │
            99个请求等待
                  │
            响应缓存,所有100个被服务

实施:
- 第一个请求触发源站获取
- 后续相同URL请求等待
- 所有请求从单个源站响应服务
- 在缓存未命中峰值时保护源站的关键

缓存失效

失效策略

策略1:基于TTL的过期
└── 让内容自然过期
└── 简单,可预测
└── 更改传播延迟

策略2:清除(立即失效)
└── 从缓存中移除特定URL
└── 快速更新传播
└── 在大规模时可能昂贵

策略3:软清除(陈旧-while-重新验证)
└── 标记内容为陈旧
└── 在获取新鲜内容时提供陈旧内容
└── 最佳用户体验

策略4:版本化URL
└── 内容更改时更改URL
└── 无需清除
└── 最佳缓存效率
└── asset.js?v=abc123 或 asset.abc123.js

策略5:缓存标签(代理键)
└── 用标识符标记内容
└── 按标签而非URL清除
└── 适用于相关内容
└── 清除所有“product-123”标记的内容

版本化模式

URL版本化:

模式1:查询参数
/styles.css?v=1.2.3
/styles.css?v=a1b2c3d4(哈希)
+ 易于实施
- 一些CDN默认不缓存查询字符串

模式2:文件名哈希
/styles.a1b2c3d4.css
+ 最佳缓存效率
+ CDN默认缓存
- 需要构建过程

模式3:路径版本化
/v1.2.3/styles.css
+ 清晰版本组织
- 可能有多个版本需清除

推荐:
- 静态资源:文件名哈希(最佳缓存效率)
- API:路径版本化(/v1/api/...)
- HTML:短TTL + 重新验证

缓存标签 / 代理键

缓存标签示例:

源站响应:
HTTP/1.1 200 OK
Surrogate-Key: product-123 category-electronics homepage
Cache-Control: public, max-age=86400

内容标记为:
- product-123(特定产品)
- category-electronics(产品类别)
- homepage(出现在首页)

清除场景:
- 产品更新:清除“product-123”
- 类别重组:清除“category-electronics”
- 首页更改:清除“homepage”

单个清除影响所有带该标签的URL。

边缘计算

边缘函数

边缘函数用例:

1. 请求操作
   - URL重写
   - 头部修改
   - 认证
   - 基于地理位置的路由

2. 响应操作
   - HTML注入(A/B测试)
   - 内容转换
   - 边缘个性化
   - 响应压缩

3. 安全
   - 机器人检测
   - 速率限制
   - WAF规则
   - 令牌验证

4. 缓存逻辑
   - 自定义缓存键
   - Vary规范化
   - 缓存绕过规则
   - 选择性清除

平台:
- Cloudflare Workers
- AWS Lambda@Edge / CloudFront Functions
- Fastly Compute@Edge
- Akamai EdgeWorkers

边缘A/B测试

边缘A/B测试:

传统(源站基础):
用户 ──► CDN ──► 源站 ──► 确定变体 ──► 响应
         │                  (由于个性化,不可缓存)
      每次缓存未命中

边缘基础:
用户 ──► 边缘Worker ──► 分配变体(cookie/header)
              │
              ├── 变体A:服务 /page-a(可缓存)
              └── 变体B:服务 /page-b(可缓存)

好处:
- 每个变体单独可缓存
- 无需每请求源站计算
- 一致变体分配
- 边缘分析

CDN选择

提供商比较

CDN提供商考虑因素:

性能:
├── 全球POP覆盖
├── 网络质量(对等)
├── 缓存命中率
└── TTFB基准

功能:
├── 边缘计算支持
├── 实时分析
├── 自定义缓存规则
├── 图像优化
├── 视频流
└── 安全功能(WAF, DDoS)

定价模型:
├── 基于带宽
├── 基于请求
├── 固定费率
└── 承诺折扣

集成:
├── API质量
├── Terraform/IaC支持
├── CI/CD集成
└── 监控集成

主要提供商:
- Cloudflare:出色的开发者体验,慷慨免费层
- Fastly:适合动态/个性化内容
- AWS CloudFront:与AWS生态系统最佳
- Akamai:企业级,全球最多POPs
- Azure CDN:与Azure生态系统最佳

最佳实践

CDN最佳实践:

1. 缓存效率
   □ 对静态资源使用内容哈希
   □ 为内容类型设置适当TTLs
   □ 实施源站屏蔽
   □ 监控缓存命中率

2. 性能
   □ 启用压缩(Brotli/Gzip)
   □ 使用HTTP/2或HTTP/3
   □ 实施预连接提示
   □ 为核心Web指标优化

3. 缓存失效
   □ 优先使用版本化URL而非清除
   □ 为相关内容使用缓存标签
   □ 尽可能实施软清除
   □ 准备好清除自动化

4. 安全
   □ 随处启用HTTPS
   □ 配置正确CORS
   □ 实施安全头部
   □ 对敏感内容使用签名URL

5. 监控
   □ 跟踪缓存命中率
   □ 监控源站负载
   □ 设置延迟警报
   □ 分析错误率

故障排除

常见问题:

1. 低缓存命中率
   - 检查Vary头部扩散
   - 验证cache-control头部
   - 查看查询字符串变化
   - 检查基于cookie的变化

2. 陈旧内容
   - 验证cache-control max-age
   - 检查清除传播延迟
   - 确认版本化策略
   - 审查源站响应头部

3. 高源站负载
   - 实施源站屏蔽
   - 启用请求合并
   - 在适当处延长TTLs
   - 为API响应添加缓存

4. 慢性能
   - 检查POP分布
   - 验证压缩已启用
   - 审查TLS配置
   - 分析源站响应时间

调试头部:
X-Cache: HIT/MISS
X-Cache-Hits: 123
Age: 3600
CF-Cache-Status: DYNAMIC/HIT/MISS

相关技能

  • edge-computing - 在CDN边缘计算
  • latency-optimization - 端到端延迟减少
  • multi-region-deployment - 全球基础设施模式
  • caching-strategies - 应用级缓存