关于CDN缓存总结摘要

CDN缓存的几点总结

  1. CDN资源的标识: url
  2. 跟HTTP缓存无关的请求头不影响CDN缓存(亲测)
  3. 不仅是静态资源,接口的数据可以做CDN缓存(亲测)
  4. CDN服务一般都有默认的缓存配置(比如一分钟),服务端可以通过设置HTTP缓存相关的Header控制是否适用CDN缓存
  5. HTTP缓存和CDN缓存分别作为客户端缓存和服务端缓存

HTTP缓存

关键字段有Expires,Cache-Control ,Last-Modified ,Etag 四个字段,Expires和Cache-Control用来确定确定缓存的存储时间,Last-Modified 和Etag则用来确定缓存是否要被更新

强制缓存

控制强制缓存的字段分别是Cache-Control和Expires,其中Cache-Control优先级比Expires高

  1. Expires: HTTP1.0的,已废弃
  2. Cache-Control: HTTP1.1中用来控制缓存时间的参数 (Cache-Control:max-age=30;xxx;)
    public: 表明响应可以被任何对象(包括:发送请求的客户端,代理服务器,等等)缓存。
    private: 表明响应只能被单个用户缓存,不能作为共享缓存(即代理服务器不能缓存它)。
    max-age=seconds: 设置缓存存储的最大周期,相对于请求的时间缓存seconds秒,在此时间内,访问资源直接读取本地缓存,不向服务器发出请求。(与expires同时出现时,max-age优先级更高)
    s-maxage=seconds: 规则等同max-age,覆盖max-age 或者 Expires 头,但是仅适用于共享缓存(比如各个代理),并且私有缓存中它被忽略。(与expires或max-age同时出现时,s-maxage优先级更高)
    no-store: 不缓存服务器响应的任何内容,每次访问资源都需要服务器完整响应
    no-cache: 缓存资源,但立即过期,每次请求都需要跟服务器对比验证资源是否被修改。(等同于max-age=0)
    

协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。控制协商缓存的字段分别有:Last-Modified / If-Modified-Since和Etag / If-None-Match,其中Etag / If-None-Match的优先级比Last-Modified / If-Modified-Since高。

  1. Last-modified: 源头服务器认定的资源做出修改的日期及时间。精确度比Etag低。包含有If-Modified-Since或 If-Unmodified-Since首部的条件请求会使用这个字段。
  2. Etag: HTTP响应头是资源的特定版本的标识符。

如何控制不使用缓存

  • F5刷新:
    (Cache-Control: max-age=0)
    浏览器会设置max-age=0,跳过强缓存判断,会进行协商缓存判断【浏览器直接对本地的缓存文件过期,但是会带上If-Modifed-Since,If-None-Match(如果上一次response带Last-Modified, Etag)这就意味着服务器会对文件检查新鲜度,返回结果可能是304,也有可能是200.】
  • 强制刷新 (command+shift+R):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control: no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。
    ctrl+F5强制刷新:
    (Cache-Control: no-cache)
    跳过强缓存和协商缓存,直接从服务器拉取资源。【浏览器不仅会对本地文件过期,而且不会带上If-Modifed-Since,If-None-Match,相当于之前从来没有请求过,返回结果是200.】
  • 如何不缓存
    Cache-Control其他字段:
    no-cache: 虽然字面意义是“不要缓存”。但它实际上的机制是,仍然对资源使用缓存,但每一次在使用缓存之前必须向服务器对缓存资源进行验证。
    no-store: 不使用任何缓存
    禁止缓存:
    Cache-Control: no-cache, no-store, must-revalidate
    Expires:设为当前时间之前
  • 强缓存存在两种形式:from memory cache 与 from disk cache (浏览器F12查看)

CDN缓存

  • cdn缓存是一种服务端缓存
  • 与http缓存规则不同的是,这个规则并不是规范性的,而是由cdn服务商来制定
  • 回源的意思就是返回源站,何为源站,就是我们自己的服务器;CDN回源,没有资源就去源站读取,有资源就直接发送给用户。
  • cdn缓存配置,整体来说,建议和http缓存配置保持统一

不一致的影响

cdn的缓存配置会受到http缓存配置的影响,而且各个cdn服务商并不完全一致,以腾讯云为例,在缓存配置的文档中特别有以下说明。
这会对我们有什么影响呢?

  1. 如果我们http缓存设置cache-control: max-age=600,即缓存10分钟,但cdn缓存配置中设置文件缓存时间为1小时,那么就会出现如下情况,文件被访问后第12分钟修改并上传到服务器,用户重新访问资源,响应码会是304,对比缓存未修改,资源依然是旧的,一个小时后再次访问才能更新为最新资源
  2. 如果不设置cache-control呢,在http缓存中我们说过,如果不设置cache-control,那么会有默认的缓存时间,但在这里,cdn服务商明确会在没有cache-control字段时主动帮我们添加cache-control: max-age=600。
    注:针对问题1,也并非没有办法,当我们必须要在缓存期内修改文件,并且不向想影响用户体验,那么我们可以使用cdn服务商提供的强制更新缓存功能,主要注意的是,这里的强制更新是更新服务端缓存,http缓存依然按照http头部规则进行自己的缓存处理,并不会受到影响。

缓存配置

  • cdn缓存的配置并不复杂, 复杂的情况在于cdn缓存配置会受到http缓存配置的影响,并且不同的cdn运营商对于这种影响的处理也都不一致,实际使用时,建议去对应的cdn服务商文档中找到对应的注意事项。
  • CDN缓存控制:如果源站设置了 no-cache 、private、 max-age = 0 都遵循源站,CDN 是不会进行缓存的。
  • 又拍云为开发者执行缓存刷新提供了主动更新和被动更新两种方式。
    1. 主动更新主要是指同名资源在源服务器更新之后,开发者手动刷新文件。又拍云提供了可视化的操作台供用户执行缓存刷新操作,同时支持 URL 刷新和规则刷新。此外开发者也可通过 API 接口完成刷新操作。
    2. 被动刷新则是等文件在 CDN 节点的缓存过期之后,节点回源拉取源服务器上最新的文件。这个过程由 CDN 自动完成,无需手动操作。

扩展

  • 动态CDN加速

  • CDN的全称是Content Delivery Network,即内容分发网络

  • 动态CDN加速:非静态数据,通过CDN的加速来起到快速回源的效果的。使用到的就是CDN的快速传输的能力。其实也就是DSA(Dynamic Site Acceleration)

    • 传统的DSA有:
      • TCP 优化:设计算法来处理网络拥堵和包丢失,加快这些情况下的数据从cdn的恢复以及一些常见的TCP瓶颈
      • Route optimization:就是优化从源到用户端的请求的线路,以及可靠性,就是不断的测量计算得到更快更可靠的路线
      • Connection management:就是边缘和源之间,包括CDN之前的线路,采用长连接,而不是每一个请求一个连接
      • On-the-fly compression:就是数据在刚刚离开源的时候就进行压缩,可以缩短在整个网络之中的流通时间
      • SSL offload:加速或者说减少一些安全监测,减少原服务器执行这种计算密集型的压力
      • Pre-fetching:有的服务可以解析HTML文件,并将原始服务器预取缓存对象嵌入到文件中
    • 更可靠的连接(只要负责连接边缘服务器,如果直接走回源线路的话,线路会很长,不可靠)
  • 使用CDN隐藏服务器真实IP

    • 隐藏服务器真实IP是解决问题最好和最快的方法,但只针对小流量,大流量同样会扛不住。
      服务器前端加CDN中转,比如阿里云、百度云加速、360网站卫士、加速乐、安全宝等,如果资金充裕的话,可以购买高防的盾机,用于隐藏服务器真实IP,域名解析使用CDN的IP,所有解析的子域名都使用CDN的IP地址。此外,服务器上部署的其他域名也不能使用真实IP解析,全部都使用CDN来解析。
    • 另外防止服务器对外传送信息泄漏IP,最常见的是,服务器不使用发送邮件功能,如果非要发送邮件,可以通过第三方代理(例如sendcloud)发送,这样对外显示的IP是代理的IP。

Reference