沉沦博客

自定义 77°
69%
0%
文章

我的博客缓存与回源策略

摘要:记一下这个博客的缓存和回源是怎么配的:三层 TTL、过期先给旧的、静态资源一年、404 只记 30 秒,以及回源只认 CDN。

·1614 字 ·约 5 分钟 · 9
目录(13 节)
  1. 以前的问题
  2. 现在是什么样
  3. 一、三层缓存,三个时间
  4. 二、过期不等于作废
  5. 三、压完只剩四分之一
  6. 四、静态资源记一年
  7. 五、404 只记 30 秒,301 记一小时
  8. 六、多余的参数直接跳回干净地址
  9. 七、HEAD 和正常访问发同一套说法
  10. 八、按人和主题分开记
  11. 九、回源只认 CDN
  12. 十、发布后自动清缓存
  13. 一句话总结

最近发现博客的加载速度存在异常,自己就鼓捣了一下缓存设置,结果越弄越糟糕,经常出现缓存过头拿不到新页的问题。还好有 AI 帮助,让它把博客的缓存和回源重做了一遍。这篇就不写过程了,写出来能把自己蠢哭…只记两件事:以前是什么样,现在是什么样。

以前的问题

  • 404 记六分钟:60 秒缓存,再加 300 秒「过期了先拿旧的顶着」。新文章发出去,之前 404 的地址还在继续 404,分享给朋友就是打不开。
  • 301 记一天:网址规则还在改,改错一次,回访的人一天内都被导向旧地址。
  • 参数在 CDN 上各占一份:服务器已经把 /?page=2 当成首页,但 CDN 按完整网址分开记。同一件衣服,衣架上挂了两百个。
  • HEAD 请求拿到不一样的答案:正常访问说「可以存 30 秒」,用命令行检查却回「别存」。代理和搜索引擎喜欢用后一种问法预热,会被误导。
  • 旧副本清不掉:上传的图片视频标了「一年内别来问」,结果几天前一次配置错误留下的旧版本也被一起钉住。以为按目录清一下就好,提交返回成功,刷新还是旧的。

现在是什么样

一、三层缓存,三个时间

谁 记多久 相当于
浏览器 30 秒 手边的小本子
CDN 边缘 5 分钟 小区门口的公告栏
源站 10 分钟 家里的原稿

一次请求,三个地方各记多久

源站的 10 分钟必须比 CDN 的 5 分钟长。不然 CDN 每次到期去拿新的,正好赶上源站也忘了,白算一遍,慢的还是读者。

二、过期不等于作废

CDN 那份过了 5 分钟,不会让读者等着,而是先把旧的递出去,同时派人去拿新的。实测过:页面明明已经过期,打开照样秒回;过几秒再看,已经悄悄换成新的了。

源站挂了还能拿一小时的旧页面顶着。部署重启那几十秒,读者看到的是旧首页,不是报错页。

三、压完只剩四分之一

首页 36.9KB,压完 9.3KB;文章页 49KB,压完 14.2KB;订阅源 162.8KB,压完 44.7KB。

压缩前后对比

压缩是源站自己做的。响应头里写了「别动我的字节」,CDN 很听话,连压缩都不做了;服务器框架自带的压缩也认这句话,一起罢工。只能自己压——压好的 Brotli 和 gzip 两份挂在缓存条目上,下次有人来直接用,不用重算。

代价是内存要算上压缩后的两份。只算正文的话,实际占用会是账面的三倍。

四、静态资源记一年

样式、脚本、图片都带内容指纹(?v=一串哈希)。指纹对得上,告诉浏览器「一年内别来问」;对不上,退成 5 分钟——防止外部链接把旧内容钉死。

主题的截图也一样,换主题才换指纹。

五、404 只记 30 秒,301 记一小时

404 的寿命对比

404 需要被记住:任何乱敲的网址都会走到这里,每次都要查数据库、渲染模板,不记会被扫网址的脚本拖垮。但只记 30 秒,过期就老实去问,够挡住扫描,也不至于让新地址在门口挂六分钟。

永久跳转从一天缩到一小时。网址规则还在改,一小时足够让旧链接少问几次,改错也能当天收敛。

六、多余的参数直接跳回干净地址

只剪四个参数,用错地方就 301:

  • /?page=2 → /
  • /p/某篇文章?page=3 → /p/某篇文章/
  • /links/?cpage=2 → /links/

utm_source 这些一律保留,统计来源还要用。

这样 CDN 上不会再出现两百份一模一样的首页。

七、HEAD 和正常访问发同一套说法

命令行检查、代理预热、搜索引擎,用的都是只问「在不在」不看内容的问法。现在它和正常访问拿到的缓存头完全一致,连 ETag 都一样。

八、按人和主题分开记

  • 后台会话:一律 private, no-store,谁也别想缓存。
  • 访客选过主题:按主题分开记,喜欢「拾光」的和喜欢「经典」的各存一份,互不串。
  • 匿名访问:共用一份。

实测过:带经典主题的请求连续三次都命中,匿名请求仍是默认主题,没有串。

九、回源只认 CDN

CDN 到源站这一段,相当于后厨到仓库。

  1. 门禁:源站只放行 CDN 的机房网段,几百个地址,一个个写进白名单。
  2. 暗号:光看地址不够,同机房其他机器也能连。CDN 每次来要带一个约定的请求头,对不上就 403。
  3. 加密:回源走 HTTPS,源站保留自己的证书。
  4. 少跑一趟:扫描器最爱打 /admin,现在 CDN 自己就回个 302 到登录页,连仓库门都不用走。上线后翻源站日志,/admin 那行再没出现过。

验证方式是翻源站日志:最近三千条里,34 条是绕开 CDN 直接来的,全被拦了。

图片和视频由 nginx 直接发,不经过 Node。判断生效没有,看指纹格式:两段是 nginx 发的,四段是 Node 发的。

十、发布后自动清缓存

每次上线,脚本自动清首页、六个列表页、订阅源和站点地图。不清的话,CDN 那 5 分钟加上「过期先给旧的」那 15 分钟,最长二十分钟读者还在看旧页面。

上传件另算。按目录清对视频这种「切片传输」的文件不生效——视频是一段一段拿的,缓存里存的也是碎片,按目录扫不到。所以清上传件是把 1267 个文件列出来,一条一条清,脚本按一千条一批提交。一分钟后抽查,全对。

一句话总结

浏览器 30 秒 → CDN 5 分钟(过期先给旧的,后台刷新)→ 源站 10 分钟 → 磁盘。

静态资源一年,404 三十秒,跳转一小时,回源只认 CDN,发布自动清。

评论9

回复 Mr.He 取消回复

  • Mr.He回复

    搞得很专业,看不懂😂

    • 沉沦作者回复

      哈哈都一样,我也不懂~又不是专业人士。

  • ymz316回复

    缓存确实可以提高访问速度,就是太难打理了。

    • 沉沦作者回复

      是啊,好麻烦,尤其是动态内容,配置不好就出问题。

  • Feng回复

    是不是有点太在意速度了,已经很快了

    • 沉沦作者回复

      速度并没有更快,只是改了下规则。

  • 沐阳回复

    CDN 的机房网段哪里搞来的😁。你的评论框可以放到评论上面,省的翻这么久

    • 沉沦作者回复

      说的对,马上去改,评论表单在上面好像更符合逻辑。

  • 皇家元林回复

    速度很快啊!用的哪家cdn?
    不过这确实太专业了。真看不懂。