性能优化之CDN缓存

2,945 阅读4分钟

性能优化之CDN缓存

适用范围

  1. 此文实现的CDN缓存方案,主要是针对根HTML的(动态的),不是静态资源的那种CDN缓存
  1. 各类型的项目都适用

受益

  1. 更好的性能(减少白屏时间)

    1. 对全球性化项目提升更明显,特别是离服务器远的国家

    2. 对SSR项目来说,效果会更明显

      1. 因为SSR项目需要用框架代码解析js代码后,才生成HTML字符串(中间可能会有调接口获取数据的阻塞)。这部分还是比较耗时的
    3. 提升效果:以一个(全球业务/SSR服务)为例(我们有准确的真实用户数据)

      1. DomContentLoaded时间(白屏时间)平均减少 1s +
      2. 越边缘的国家越明显,甚至能达到2s

006APoFYly8gqq6f5r5n8g308q08q7t9.gif

  1. 帮服务端减轻压力,抵御部分攻击流量

    1. 对SSR项目来说,能抗住的QPS非常低。开启CDN缓存后,能帮忙抵御部分攻击流量,也可以节省服务器资源

如何开启CDN缓存?

步骤:

  1. 拉公司内部的CDN oncall,给他域名,让他帮忙开启CDN缓存,并且策略是follow源站

    1. follow源站是啥意思? 就是follow Nginx的Cache-Control的配置(公司内部,开发是可以自己去配nginx的)

      1. 比如,你在nginx的path: /abc下 开启了 Cache-Control: 1800(单位:s),那么CDN缓存的时间就是1800s
      2. 用这个策略,我们可以自己精确配置各path的CDN缓存时间,可以方便以白名单的方式,逐步放量

注意点:

  1. CDN缓存是url级别的

    1. 比如:你访问 www.example.com/abc 一次后,得到了CDN缓存,下次访问www.example.com/abc?q=1 时,就没有缓存,因为缓存是精准匹配url的
  1. 为了提高CDN缓存的命中率,可以让CDN缓存忽略某些url的query吗?

    1. 可以, 可以让CDN oncall配置 不识别某些query

如果发了bug到线上去,回滚后,如何快速清除线上的CDN缓存?

  1. 一般公司内有平台,可以自己输入url,去清除CDN缓存
  2. 或者拉公司内部的CDN oncall清除

2种方法都行,如果是自己手动清理的话,但有注意点:

  • CDN缓存是只能url级别的清除。 比如一个域名下有10个path有缓存,就要把这10个path,都贴到平台里去,提交 清除

  • 所以,建议:维护一个CDN缓存的path白名单,方便后续管理和维护

开启CDN缓存后,架构上有什么变动?

命中CDN缓存的情况,请求将不会回源(回源:不会回到你的node server端)

  1. 很多SSR服务在开发的时候就没考虑过不回源的情况,有部分数据可能只在server端获取,然后通过框架实例 带到client端去。如果是这种情况,开启CDN缓存后,就需要改造代码了。改造方法:

    1. 换成前端的js去请求获取数据

    2. 一些接口之前在server端是rpc,并且不对外提供http的接口,这种就要自己用node server做接口 给 自己的前端调用了

需要注意的坑

  1. 同上,需要去检查数据的获取,如果只在server端调接口,而前端不调,那这种数据就要格外注意。需要去改造到前端去调接口

  2. 注意不要缓存到接口!!! 最好渐进式的配置path的缓存,梳理清楚前后端的path使用

  3. 提前想好回滚方案,预防未来可能有bug发到线上

CDN缓存的副作用

也不算坏作用吧,还是看场景

副作用:

  1. 滞后迭代:

    • 比如缓存24h,那么你发布了新功能后,24h后用户才能体验到新功能
  2. 不能做智能页面:

    • 因为命中CDN缓存后,将不会回源,这样页面就是纯静态页了(至少首屏是固定的)。如果将来要做动态页面,比如根据不同的人群 显示不同的内容,这种能力,将很难和CDN缓存共存。
      • 除非投放侧可以智能增加query,那么可以做到根据query的不同,为不同人群缓存不同的页面

码字不易,点赞鼓励