SEO 百科

服务端缓存

本页目录

服务端缓存

服务端缓存 是把现成的响应存一份,位置在服务器本身或者它前面的节点上。同样的请求再来时直接返回这一份,不再执行程序,也不再查数据库。它省掉服务器这一侧的算力,存了什么、存多久决定代价。爬虫和访客拿到新版还是旧版,也由这一层决定。

服务器这一侧存的内容

按存的位置分两层。源服务器自己存的是整页缓存与片段缓存:前者存生成好的 HTML,后者只存页面里反复出现的一块,比如导航、页脚、文章列表。源服务器前面还有一层托管缓存,MDN 说它由服务开发人员明确部署,用来降低源服务器负载、有效交付内容[1]。反向代理和 CDN 是这一层的常见形态,service worker 配合缓存 API 也算在内[1]。Google 说明这条标头规定中间缓存如何存响应、存多久,CDN 与反向代理都在它的约束之列[4]。共享缓存指给很多人复用响应的那一层,浏览器本机那一层叫私有缓存。

能存的东西按动静分:

  • 静态资源:CSS、JavaScript、图片、字体,内容不随访客变化。
  • 公共 HTML:文章页、列表页这类不需要登录就能看到的页面。
  • 页面片段:动态页里反复出现的那几块,其余部分每次重新生成。
  • 上游响应:反向代理存住接口返回的 JSON,程序不再重复调用后端。

哪些内容默认不存,节点产品有自己的规矩。Cloudflare 说明它只按文件扩展名判断要不要缓存,不看 MIME 类型,默认存的是 png、webp、avif、gif、css、js、svg、pdf、mp4 这类文件,HTML 与 JSON 不在默认列表里[2]。想让 HTML 停在节点上,得自己配规则或者改响应头。

决定存取范围的指令

HTTP 缓存的状态定义在 RFC 9111 里,响应有新鲜与过期两种状态,指令决定谁能存、存多久[3]。落到配置上,几个指令各管一段范围:

指令 作用对象 效果
max-age=<秒> 私有缓存与共享缓存 新鲜期长度
s-maxage=<秒> 只作用共享缓存 覆盖 max-age,节点按这个值存
public 所有缓存 响应可被任何对象存下
private 只本机浏览器 共享缓存不得存
no-cache 存它的每一层 用前先回源确认,副本照存
no-store 所有缓存 一份都不留

回到源站确认这一步,业内叫回源,指的是缓存不再用本地副本,转而向源服务器要一份新的。public 容易用错。请求里的 Authorization 是授权标头,MDN 提示只有这时仍需要存储响应才写 public[1]。给了 max-age,响应本来就会进共享缓存。含登录态的响应漏写 private,节点会把甲用户看到的页面发给乙用户。

同一网址有两种副本时要用 Vary。缓存本来按 URL 区分响应,加上 Vary: Accept-Language 之后,缓存改按 URL 与请求标头的组合分键,两种语言各存一份[1]。用 Cookie 区分访客时不要把它写进 Vary,MDN 给出的做法是改用 Cache-Control: private[1]。

缓存出错对抓取的影响

节点上留着旧副本,爬虫抓到的就是旧内容,收录停在旧版本。两处标头在这一步同时起作用。Last-Modified 一面服务缓存验证,一面被引擎用来调整抓取节奏,MDN 说内容管理系统会用它显示最后修改时间,爬虫会利用它调整抓取频率[1]。响应快慢决定单位时间能抓回多少页:Google 说明抓取容量上限随站点响应状况升降,响应快时上限升高,变慢或出现服务器错误时上限下降[5];百度说明 Baiduspider 会按内容更新频率和服务器压力调整抓取频次[6]。

存错内容的后果更直接:

  • 节点把 404 或 5xx 存住,爬虫连续取到错误状态,页面可能被判定为已失效。
  • 重定向被缓存下来,改版后的新地址抓不到,收录停在旧地址。
  • 带登录态的 HTML 进了共享缓存,下一个访客被当成已登录用户,返回的是残缺页。
  • 只存了某一语言的副本却发给所有人,其他语言的内容进不了索引。

配置的次序

先给所有响应一个默认值,再按资源类型分档,最后留一条主动清除的路。

  1. 每个响应都显式带 Cache-Control。HTTP 的设计是尽量多缓存,缺这个标头时客户端会自己猜一个时长,MDN 把这种做法叫启发式缓存,并建议所有响应显式指定[1]。
  2. 公共 HTML 用 no-cache,每次使用前回源确认,页面没变时只返回 304 Not Modified[1]。
  3. 带指纹的静态文件给一年,Cache-Control: public, max-age=31536000。指纹指从文件内容算出来的一串字符,内容一改它就换。
  4. 含个人信息的响应加 private,接口响应另按数据敏感度设短的新鲜期。
  5. 准备好清除节点的通道。HTTP 缓存规范本身没有定义删除缓存的方法,托管缓存可以通过面板操作、接口调用或者重启实时删掉已经存下的响应[1]。发布后仍抓到旧副本,就走这条通道。

附录

参见

参考资料

官方(境外)

  1. 《HTTP 缓存》,MDN Web 文档。
  2. 《Default cache behavior》,Cloudflare Docs。
  3. 《RFC 9111 : STD 98 : HTTP Caching》,IETF,2022-06。
  4. 《使用 HTTP 缓存防止不必要的网络请求》,web.dev。
  5. 《面向大型网站所有者的抓取预算管理指南》,Google 搜索中心。

官方(国内)

  1. 《平台工具使用手册(抓取频次)》,百度搜索资源平台,2020-08-14 更新。

外部链接

无。