缓存策略设计
缓存不是"开了就好"。设计不当的缓存会让用户看到过期内容,或者根本没有缓存效果。
Cache-Control 头:控制缓存行为的核心
Cache-Control 是 HTTP 响应头,告诉浏览器和 CDN 如何缓存这个资源。
| 指令 | 含义 |
|---|---|
max-age=3600 | 缓存 3600 秒(1 小时) |
s-maxage=86400 | CDN 缓存 86400 秒(24 小时),浏览器用 max-age |
no-cache | 必须先向服务器验证,才能使用缓存 |
no-store | 不缓存,每次都从服务器获取 |
public | 可以被 CDN 缓存 |
private | 只能被浏览器缓存,不能被 CDN 缓存 |
immutable | 内容永不变,浏览器绝不重新验证 |
不同资源的缓存策略
graph TD
A[资源类型] --> B{是否会变化?}
B -->|永不变化
哈希文件名| C["Cache-Control: public, max-age=31536000, immutable"] B -->|偶尔变化| D{是否有版本号?} D -->|有版本号| E["Cache-Control: public, max-age=86400"] D -->|没有版本号| F["Cache-Control: public, max-age=3600"] B -->|经常变化
HTML 页面| G["Cache-Control: public, max-age=0, must-revalidate"] B -->|私人数据
购物车、用户信息| H["Cache-Control: private, no-store"]
哈希文件名| C["Cache-Control: public, max-age=31536000, immutable"] B -->|偶尔变化| D{是否有版本号?} D -->|有版本号| E["Cache-Control: public, max-age=86400"] D -->|没有版本号| F["Cache-Control: public, max-age=3600"] B -->|经常变化
HTML 页面| G["Cache-Control: public, max-age=0, must-revalidate"] B -->|私人数据
购物车、用户信息| H["Cache-Control: private, no-store"]
推荐配置
| 资源类型 | 推荐 Cache-Control | 原因 |
|---|---|---|
style.a3f4b8c1.css(哈希文件名) | public, max-age=31536000, immutable | 文件名变了就是新文件,旧文件永久缓存 |
logo.png(版本化) | public, max-age=2592000 | 一个月更新一次的静态资源 |
index.html | public, max-age=0, must-revalidate | 每次验证,保证内容最新 |
| API 响应(公开) | public, s-maxage=60 | CDN 缓存 60 秒 |
| API 响应(用户相关) | private, no-store | 不能 CDN 缓存 |
| 购物车、支付 | no-store | 绝对不缓存 |
Nginx 缓存头配置示例
# 静态资源(哈希文件名)- 永久缓存
location ~* \.(css|js|woff2)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
}
# 图片 - 缓存 30 天
location ~* \.(jpg|jpeg|png|gif|webp|svg|ico)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}
# HTML - 每次验证
location ~* \.html$ {
expires -1;
add_header Cache-Control "no-cache, must-revalidate";
}
Cloudflare 缓存配置
Cache Rules(推荐方式)
Cloudflare → Caching → Cache Rules → Create Rule
规则示例:缓存静态资源 1 年
- 匹配条件:文件扩展名 = .css or .js or .png or .jpg
- 缓存设置:Cache everything,Edge TTL = 365 days
规则示例:不缓存 API
- 匹配条件:URI 路径以 /api/ 开头
- 缓存设置:Bypass cache
手动清除缓存
# 通过 Cloudflare API 清除指定 URL 的缓存
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
--data '{"files":["https://example.com/style.css?v=5f3ef23d"]}'
Cloudflare 后台操作:Caching → Configuration → Purge Cache
动静分离架构
graph LR
subgraph 静态资源(CDN 直接返回)
C[CSS / JS / 图片] --> CF[Cloudflare CDN]
CF --> U[用户]
end
subgraph 动态内容(回源)
U2[用户] --> CF2[Cloudflare CDN]
CF2 -->|Cache miss| S[源服务器]
S --> CF2
CF2 --> U2
end
动静分离的关键:
1. 静态资源用哈希文件名(style.a3f4b8c1.css)— 内容变了就换文件名,CDN 自动失效
2. HTML 页面不长期缓存,或者设置短 TTL(5–60 秒)
3. 用户相关数据永远不走 CDN 缓存
本章执行清单
- [ ] 检查你的静态资源(CSS、JS、图片)是否设置了合适的 Cache-Control 头
- [ ] 确认购物车、用户登录状态等个人数据的响应头有
private或no-store - [ ] 在 Cloudflare 配置 Cache Rules,区分静态资源和动态内容
- [ ] 测试:修改 CSS 后,用
curl -I确认缓存正确更新
下一章:邮件记录与投递——SPF、DKIM、DMARC 是什么,为什么你的邮件会进垃圾箱。