秒杀项目实践(四)——前端静态页面资源缓存

PunkLu 2019年12月22日 103次浏览

前端静态页面资源缓存

首先使用JMeter压测下前端静态页面的访问速度,uri:/resources/getitem.html?id=6,其他不变。可以看到,如果Nginx不在固态硬盘上,获取前台页面的接口性能并不够好。可以通过静态请求CDN来优化。

阿里云CDN配置

在阿里云中选择CDN服务,进入域名管理,添加CDN的加速域名,选择业务类型(如图片小文件),源站信息即上线后的nginx服务器ip。选择完加速端口(80或443)、加速区域后点击下一步即配置完成。然后配置CNAME,进入域名管理,解析一个已购买的域名,添加一个解析规则,记录类型不是常规的A类型(即域名-ip地址映射),而是CNAME地址,即将域名指向另一个新域名,解析新域名的IP地址。这里的地址需要跟之前配置CDN时候的加速域名一致。记录值选择CDN配置里边由阿里云生成的CNAME地址。选择完解析路线等信息后保存即生效。

这样一来,当用户发起DNS请求时,请求到达DNS服务器,DNS服务器查询到这条请求是CNAME地址,DNS不会进行解析,会把这个请求发给配置CDN时阿里云生成的CNAME地址。CNAME地址对应的服务器会解析出来用户就近的CDN节点,让用户访问这个CDN节点上的IP地址。然后这个就近的CDN地址判断本地是否有请求的文件,如果有直接返回给用户,节省访问应用服务器的时间。没有的话就回源到CDN配置的服务器地址上请求资源并在返回给用户的同时保存在本地。下一次用户再访问相同资源时就可以直接返回给用户了。

深入CDN-Cache Control响应头

cache-control是服务端返回给客户端的响应头的内容,是告诉客户端返回的数据可不可以缓存,以什么样的策略缓存。

cache-control的状态:

  1. private

    默认配置,客户端可以缓存,代理服务器不可缓存

  2. public

    客户端和代理服务器(nginx反向代理、CDN网络等)都可以缓存

  3. max-age=xxx

    缓存的内容将在xxx秒后失效

  4. no-cache

    强制向服务端再验证一次,会将内容缓存起来,下一次发送请求的时候会再验证一下缓存是否可用

  5. no-strore

    不缓存请求的任何返回内容

缓存有效性判断:

在第一次的请求时,服务端将请求资源的内容通过HASH或BASE64等方式生成ETag(资源唯一标识)并返回给浏览器,浏览器会存储下来ETag。下一次请求的时候,将之前缓存下来内容的ETag的值一起发送到服务器上,用来验证是否可用,服务端会用ETag的值和服务端本地的资源内容的ETag的值做比较,若比较是一致的,会返回304 not modify,告诉浏览器缓存有效,直接使用缓存的内容即可。并且服务端响应的时候会返回一个Last-modified的值(即资源最后被修改的时间)。客户端在请求的时候带上If-modified-Since(即客户端发送的匹配资源最后修改的时间的标识符),若这个时间早于Last-modified值,说明缓存是无效的,若晚于Last-Modified的值,说明缓存有效。

选择策略:看接口返回的数据是否允许被缓存,不允许被缓存就是no-store,允许被缓存再看每次请求是否重新验证,是的话就是no-cache,不是的话再看是否允许被代理服务器缓存,允许就是public,不允许就是private。

浏览器三种刷新方式

  1. 回车刷新或a链接

    看cache-control对应的max-age是否为仍然有效,有效则直接from cache,若cache-control中为no-cache,则直接缓存协商逻辑

  2. F5刷新或command+R刷新

    去掉cache-control中的max-age或直接设置max-age为0,然后进入缓存协商逻辑

  3. 强制刷新:ctrl+F5或command+shift+R刷新

    去掉cache-control和协商头,强制刷新

CDN自定义缓存策略

  1. 可自定义目录过期时间

    即不论浏览器和源站的cache-control是什么值,CDN都可以自定义和源站的资源的过期时间,超过过期时间后,CDN会强制回源一次。

  2. 可自定义后缀名的过期时间

    即针对html、css、js等资源文件自定义过期时间

  3. 可自定义对应权重

    比如说,假如自定义后缀名的过期时间的权重比自定义目录过期时间的权重要大,则优先执行后缀名的过期时间。

  4. 可通过界面或api强制CDN对应目录刷新(非保成功)

    强制CDN回源刷新资源,但是因为网络等原因不一定保证成功。

静态资源部署策略

静态资源如果名称不变,但是更改过之后,如果没到之前设置的过期时间,浏览器访问到的还是旧的资源文件,为了解决这个问题,可以使用:

  1. 带版本号部署

    但是维护起来非常困难。

  2. 使用摘要做文件名部署

    新老版本并存,资源(如js)部署完再部署html。且支持回滚。

对应的静态资源保持生命周期内不会变,max-age可设置的很长,无视失效更新周期。

html文件设置no-cache或较短max-age,以便于更新。

html文件仍然设置较长的max-age,依靠动态地获取版本号请求发送到后端,异步下载最新的版本号的html展示渲染在前端。