接入 CDN 之后:缓存命中率和它带来的新问题

米阳 2024-9-14 5 9/14

站点访问变慢之后,第一反应是上 CDN。接完确实快了,但也带来一堆新问题:后台改内容不生效、日志看不到真实 IP、缓存规则一错全站乱掉。

先看该不该上

CDN 的价值在于「把静态资源放到离用户近的地方」。如果访客主要在本地、服务器也在本地,CDN 收益有限。我的情况是访客分散在全国,服务器在杭州,北方用户首屏明显慢,这才值得上。

接哪些内容

  • 图片、CSS、JS:必须走 CDN,占流量的 90%
  • 文章页 HTML:可以走,但要设短缓存(5~10 分钟)
  • 后台、接口:绝不能走

缓存规则

/wp-content/uploads/*   缓存 30 天,忽略参数
/wp-content/themes/*    缓存 7 天
/wp-admin/*             不缓存
/wp-json/*              不缓存
/api/*                  不缓存

「忽略参数」很重要:很多主题会给静态资源加 ?ver=1.2 之类的参数,如果 CDN 把参数当成缓存 key,同一张图会缓存几十份,命中率暴跌。

命中率怎么看

控制台一般有「缓存命中率」指标。健康值 85% 以上。低于 70% 说明规则有问题,常见原因:

  1. 缓存时间太短,还没命中就过期了
  2. 参数没忽略,URL 千变万化
  3. 回源时带了 Cache-Control: no-cache,覆盖了 CDN 规则
  4. 源站的 Set-Cookie 让 CDN 不敢缓存

第 4 条最隐蔽:PHP 默认会给每个响应带上 Set-Cookie: PHPSESSID=...,CDN 看到 Set-Cookie 就不缓存。要在 Nginx 里去掉:

location ~* \.(jpg|png|css|js)$ {
    add_header Cache-Control "public, max-age=2592000";
    proxy_hide_header Set-Cookie;
}

改内容不生效

这是最烦的。有三种解法:

  1. 后台「刷新 CDN 缓存」,按 URL 刷
  2. 发布时自动调 CDN 的刷新接口(需要 API 权限)
  3. 给 HTML 设很短的缓存(比如 60 秒),静态资源长期缓存

我选的是第三条为主、第一条为辅。发新文章等一分钟就生效,不用每次手动刷。

真实 IP

CDN 回源时,源站看到的 IP 全是 CDN 节点。要拿真实 IP,得信任 CDN 的 X-Forwarded-For 头:

set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

10.0.0.0/8 要换成 CDN 官方给的回源 IP 段,不能乱填——否则有人伪造 XFF 头就能骗过限流和封禁。

成本

流量包按 GB 计费,图片多的站要算清楚。我做了图片压缩和 webp 转换之后,月流量从 80G 降到 20G,CDN 费用也跟着降。

结论

CDN 不是「接上就快」,规则、命中率、刷新机制都要配好。接之前先把图片压缩做掉,效果比 CDN 还明显。

- THE END -

米阳

9月14日11:10

最后修改:2024年9月14日
0

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论