HTTP与CDN缓存配置全攻略:提升性能的实战指南

一、HTTP缓存机制:从理论到实践

1.1 缓存控制核心头字段

HTTP缓存通过Cache-ControlExpires头实现资源生命周期管理。Cache-Controlmax-age指令(单位秒)定义客户端缓存有效期,例如:

  1. Cache-Control: max-age=3600, public

public表示响应可被任何中间节点缓存,private则限制为终端用户设备。no-cache要求每次请求需向服务器验证,no-store禁止存储任何副本。

Expires头(GMT格式时间戳)作为HTTP/1.0的替代方案,需注意与max-age的优先级关系:当两者共存时,Cache-Control优先生效。

1.2 验证机制:ETag与Last-Modified

ETag(实体标签)通过唯一哈希值标识资源版本,配合If-None-Match头实现条件请求:

  1. GET /api/data HTTP/1.1
  2. If-None-Match: "686897696a7c876b7e"

服务器返回304 Not Modified时,客户端可复用本地缓存。Last-ModifiedIf-Modified-Since组合提供基于时间戳的验证,但精度仅到秒级,不如ETag精确。

1.3 缓存失效策略

强制刷新(Ctrl+F5)会添加Cache-Control: no-cache头,绕过所有缓存。编程式失效可通过修改资源URL(如添加版本号style.v2.css)或发送PURGE请求(需CDN支持)实现。

二、CDN缓存架构与配置要点

2.1 CDN工作原理

CDN通过全球节点缓存静态资源,用户请求被导向最近边缘节点。回源流程触发条件包括:

  • 节点无缓存(首次访问)
  • 缓存过期(TTL到期)
  • 收到PURGE请求

典型回源配置需指定源站地址、协议(HTTP/HTTPS)及回源HOST头。

2.2 缓存规则配置

2.2.1 目录级缓存策略

按文件类型设置TTL:

  1. /static/js/*.js → TTL 86400秒(24小时)
  2. /static/img/*.png → TTL 2592000秒(30天)

动态内容(如API响应)建议设置TTL 0(不缓存)或通过Cache-Control: s-maxage=60控制边缘节点缓存。

2.2.2 查询字符串处理

默认策略下,URL参数变化会生成独立缓存。可通过配置忽略特定参数:

  1. 忽略参数:utm_source, _ts
  2. 保留参数:id, token

或启用参数折叠(将不同参数的请求指向同一缓存)。

2.3 高级功能实现

2.3.1 缓存预热

通过API批量推送热门资源至CDN节点,避免首屏加载延迟。示例预热请求:

  1. curl -X POST "https://cdn.example.com/cache/preload" \
  2. -H "Authorization: Bearer TOKEN" \
  3. -d '{"urls":["/home.js","/logo.png"]}'

2.3.2 边缘计算

部分CDN支持在节点执行JavaScript(如Lambda@Edge),实现A/B测试或个性化内容修改:

  1. // 示例:根据UA头修改响应
  2. addEventListener('fetch', event => {
  3. event.respondWith(handleRequest(event.request))
  4. })
  5. async function handleRequest(request) {
  6. const ua = request.headers.get('user-agent')
  7. if (ua.includes('Mobile')) {
  8. return new Response(mobileContent, {headers})
  9. }
  10. return fetch(request)
  11. }

三、性能优化实战技巧

3.1 缓存命中率提升

  • 资源指纹:使用Webpack的[contenthash]生成唯一文件名
  • HTTP/2推送:预加载关键CSS/JS
    1. Link: </app.css>; rel=preload; as=style
  • Service Worker:离线缓存策略
    1. cache.add('/critical.js')
    2. event.respondWith(caches.match(request) || fetch(request))

3.2 调试与监控

  • Chrome DevTools:Network面板查看Size列的(from cache)标识
  • CDN日志分析:关注X-Cache-Status: HIT/MISS
  • 实时监控:Prometheus采集CDN节点指标
    1. scrape_configs:
    2. - job_name: 'cdn'
    3. static_configs:
    4. - targets: ['cdn-metrics.example.com:9091']

四、常见问题解决方案

4.1 缓存污染问题

现象:旧版本资源持续被服务
解决

  1. 启用CDN的Force Refresh功能
  2. 修改资源URL版本号
  3. 设置Cache-Control: immutable(适用于不变资源)

4.2 动态内容缓存

场景:API响应需个性化但部分可缓存
方案

  • 使用Vary: Accept-Encoding, Authorization
  • 实现两级缓存:边缘节点缓存匿名请求,源站处理认证请求

4.3 跨域资源共享(CORS)

配置示例

  1. Access-Control-Allow-Origin: *
  2. Access-Control-Allow-Methods: GET, HEAD
  3. Access-Control-Max-Age: 86400

CDN需确保这些头不被源站响应覆盖。

五、配置检查清单

  1. 静态资源
    • 确认Cache-Control: max-age=31536000(1年)
    • 启用Brotli/Gzip压缩
  2. HTML文件
    • 设置Cache-Control: no-cache
    • 添加Vary: Accept-Encoding
  3. CDN配置
    • 验证回源协议与源站一致
    • 检查SSL证书链完整性
    • 配置IP白名单防止滥用

通过系统性配置HTTP头与CDN规则,可显著降低源站负载(典型案例减少70%回源请求),同时将页面加载速度提升40%以上。建议每季度审查缓存策略,适应业务发展需求。