网站建设时怎么平衡使用网站缓存?
下面这套方法,能让你在“速度、鲜度、成本、正确性”之间取得平衡,并且可直接落地到工程与运维。
一、先把内容分好类(决定是否该缓存)
按“变化频率 × 个性化程度”划三类,后续策略各不相同:
静态资源:CSS/JS、字体、图片、视频、图标(几乎不变,可强缓存)
半动态页面/接口:列表页、详情页、公共资讯、可容忍几十秒—几分钟延迟(可弱缓存+再验证)
个性化/敏感内容:登录态页、购物车、订单、报表、后台(一般不缓存或仅在服务端做对象缓存)
二、分层缓存要各司其职(避免“重复造轮子”)
浏览器缓存:减少回访成本,配合文件指纹做“长期不变”。
CDN/边缘缓存(s-maxage / Surrogate-Control):挡住九成流量回源。
反向代理缓存(Nginx/Envoy):作为CDN后的兜底层。
应用层缓存(内存/Redis):对象缓存、查询结果缓存。
数据库层:尽量少依赖其“查询缓存”,用上层对象缓存替代。
三、策略矩阵(可直接用的 Header/TTL)
1) 静态资源(带指纹文件名,如 app.9fa2c.js)
命名:/assets/app.[hash].js
响应头:
Cache-Control: public, max-age=31536000, immutable
Vary: Accept-Encoding
要点:每次发版换文件名,而不是改 TTL。
2) HTML/页面类(可接受 1–5 分钟延迟)
响应头(给浏览器):
Cache-Control: public, max-age=60, must-revalidate, stale-while-revalidate=30
CDN 层(优先用 s-maxage/Surrogate-Control):
Cache-Control: public, s-maxage=300, stale-while-revalidate=300, stale-if-error=86400
要点:用户几乎总拿到“很新”的页面;CDN 后台悄悄回源更新(SWR)。
3) API(GET 可缓存、POST/PUT 不缓存)
公共 GET:
Cache-Control: public, max-age=0, s-maxage=120, stale-while-revalidate=30
ETag: "abc123"
条件请求:客户端带 If-None-Match 或 If-Modified-Since,命中直接 304。
登录态/敏感接口:
Cache-Control: no-store
Vary: Authorization
要点:只让幂等的 GET 可缓存;其余 no-store。
4) 重定向/错误
301/308:可缓存 1 天以上;302/307:短缓存或不缓存。
404:短缓存(30–60 秒)防抖;5xx:不缓存,但可在 CDN 启用 stale-if-error 用旧内容兜底。
四、失效与更新(把“刷新缓存”做成标准动作)
文件指纹/版本号:前端静态资源唯一正确姿势。
标签化清理(Cache-Tag/Surrogate-Key):发布文章时,按标签批量 Purge 相关页面。
Webhook 触发:CMS 发布后自动通知 CDN Purge(优先 Soft Purge+SWR)。
条件再验证:借助 ETag/Last-Modified 减小回源成本。
灰度:先对 5–10% 路径或地区放宽 TTL,观察命中率与错误率。
五、个性化与权限(最容易“误伤缓存”的地带)
避免 Vary: Cookie 覆盖全站,否则几乎等于不缓存。
做法 A:登录态页面 Cache-Control: private, no-store;公共页继续强缓存。
做法 B:把“与身份无关的区块”切边缘片段(ESI/Edge Side Includes),公共区块缓存、个性化区块回源。
做法 C:为 AB 测试、语言、设备等精确定义 Key(例如只对 Accept-Language/Device 做 Vary)。
六、SEO 与抓取
列表/详情可用 SWR(SWR 不会返回过期很久的内容)。
重要页面更新后做精准 Purge,避免搜索引擎长时间看到旧内容。
站点地图与结构化数据页可设置较短 s-maxage,确保新内容尽快可见。
七、观测与目标(以数据调节“平衡点”)
关注 5 组核心指标:
CDN 命中率:静态资源 ≥ 95%,HTML ≥ 70% 为佳。
TTFB:核心页面 < 200ms(边缘命中时)。
回源 QPS:SWR 后回源应显著下降。
再验证比例:304/200 比例越高越省带宽。
错误兜底率:stale-if-error 服务旧内容的次数与时长应受控。
八、Nginx/CDN 参考片段(按需微调)
Nginx 反向代理缓存:
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=htmlcache:200m max_size=5g inactive=10m use_temp_path=off;
map $http_cookie $vary_user { "~*session=" 1; default 0; }
server {
location / {
proxy_cache htmlcache;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_ignore_headers Set-Cookie;
proxy_no_cache $vary_user; # 登录态不缓存
proxy_cache_bypass $vary_user; # 登录态不走缓存
proxy_cache_valid 200 1m;
proxy_cache_valid 301 1h;
proxy_cache_valid 404 1m;
proxy_cache_use_stale updating error timeout http_500 http_502 http_504;
add_header Cache-Control "public, s-maxage=300, stale-while-revalidate=300" always;
}
}
静态资源(带指纹)示例:
location /assets/ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
}
}
九、常见坑(以及替代做法)
全站 no-cache:命中率极低 → 仅对个性化/敏感路径 no-store,其余分级缓存。
长 TTL 却无 Purge:一改内容到处不一致 → 上 “标签化清理 + SWR”。
Cookie/查询串进入 Cache Key:导致击穿 → 白名单化 Query 参数、忽略无关 Cookie。
把 5xx 也缓存了:事故放大 → 5xx 不缓存,用 stale-if-error。
ETag/Last-Modified 不统一:再验证失效 → 统一由网关或应用生成,弱/强 ETag 一致化。
把私有数据缓存到 CDN:合规风险 → 登录态和含个人信息的响应 private, no-store。
十、按业务类型给 3 套起步参数
内容站/B2B 官网:
静态资源:immutable, 1y
HTML:s-maxage=300, SWR=300;发布时 Tag Purge
API 列表:s-maxage=120 + ETag
电商/活动页:
列表页:s-maxage=60–120 + SWR
详情页:普通商品 s-maxage=120,库存/价格走独立 API(GET + ETag,或 WebSocket 实时)
结算/订单:no-store
SaaS 控制台:
应用壳(HTML 框架)短缓存 s-maxage=60
数据接口:登录态 no-store,报表类 GET 可 s-maxage=30–60 + ETag
十一、上线流程(降低改动风险)
只对 /assets/ 先强缓存,验证回滚。
对 公共 HTML 按路径逐步加 s-maxage & SWR。
为 发布/回滚 写一键化脚本:打 Tag、触发 Purge、通知监控。
一周内根据命中率/TTFB迭代 TTL;达标后再推广到更多路径/地区。
一句话总括:
用“文件指纹+长 TTL”稳住静态资源,用“短 TTL + stale-while-revalidate + 精准 Purge”管好公共页面,用“no-store + 明确 Vary”保护个性化与敏感数据;再用指标驱动微调 TTL 和 Key,就能在速度与鲜度之间取到最优解。需要,我可以根据你的站点结构出一份“按路径的缓存策略清单”和可执行的 CDN 规则。