性能优化之CDN缓存
适用范围
- 此文实现的CDN缓存方案,主要是针对根HTML的(动态的),不是静态资源的那种CDN缓存
- 各类型的项目都适用
受益
-
更好的性能(减少白屏时间)
-
对全球性化项目提升更明显,特别是离服务器远的国家
-
对SSR项目来说,效果会更明显
- 因为SSR项目需要用框架代码解析js代码后,才生成HTML字符串(中间可能会有调接口获取数据的阻塞)。这部分还是比较耗时的
-
提升效果:以一个(全球业务/SSR服务)为例(我们有准确的真实用户数据)
- DomContentLoaded时间(白屏时间)平均减少 1s +
- 越边缘的国家越明显,甚至能达到2s
-
-
帮服务端减轻压力,抵御部分攻击流量
- 对SSR项目来说,能抗住的QPS非常低。开启CDN缓存后,能帮忙抵御部分攻击流量,也可以节省服务器资源
如何开启CDN缓存?
步骤:
-
拉公司内部的CDN oncall,给他域名,让他帮忙开启CDN缓存,并且策略是follow源站
-
follow源站是啥意思? 就是follow Nginx的Cache-Control的配置(公司内部,开发是可以自己去配nginx的)
- 比如,你在nginx的path: /abc下 开启了 Cache-Control: 1800(单位:s),那么CDN缓存的时间就是1800s
- 用这个策略,我们可以自己精确配置各path的CDN缓存时间,可以方便以白名单的方式,逐步放量
-
注意点:
-
CDN缓存是url级别的
- 比如:你访问 www.example.com/abc 一次后,得到了CDN缓存,下次访问www.example.com/abc?q=1 时,就没有缓存,因为缓存是精准匹配url的
-
为了提高CDN缓存的命中率,可以让CDN缓存忽略某些url的query吗?
- 可以, 可以让CDN oncall配置 不识别某些query
如果发了bug到线上去,回滚后,如何快速清除线上的CDN缓存?
- 一般公司内有平台,可以自己输入url,去清除CDN缓存
- 或者拉公司内部的CDN oncall清除
2种方法都行,如果是自己手动清理的话,但有注意点:
-
CDN缓存是只能url级别的清除。 比如一个域名下有10个path有缓存,就要把这10个path,都贴到平台里去,提交 清除
-
所以,建议:维护一个CDN缓存的path白名单,方便后续管理和维护
开启CDN缓存后,架构上有什么变动?
命中CDN缓存的情况,请求将不会回源(回源:不会回到你的node server端)
-
很多SSR服务在开发的时候就没考虑过不回源的情况,有部分数据可能只在server端获取,然后通过框架实例 带到client端去。如果是这种情况,开启CDN缓存后,就需要改造代码了。改造方法:
-
换成前端的js去请求获取数据
-
一些接口之前在server端是rpc,并且不对外提供http的接口,这种就要自己用node server做接口 给 自己的前端调用了
-
需要注意的坑
-
同上,需要去检查数据的获取,如果只在server端调接口,而前端不调,那这种数据就要格外注意。需要去改造到前端去调接口
-
注意不要缓存到接口!!! 最好渐进式的配置path的缓存,梳理清楚前后端的path使用
-
提前想好回滚方案,预防未来可能有bug发到线上
CDN缓存的副作用
也不算坏作用吧,还是看场景
副作用:
-
滞后迭代:
- 比如缓存24h,那么你发布了新功能后,24h后用户才能体验到新功能
-
不能做智能页面:
- 因为命中CDN缓存后,将不会回源,这样页面就是纯静态页了(至少首屏是固定的)。如果将来要做动态页面,比如根据不同的人群 显示不同的内容,这种能力,将很难和CDN缓存共存。
- 除非投放侧可以智能增加query,那么可以做到根据query的不同,为不同人群缓存不同的页面
- 因为命中CDN缓存后,将不会回源,这样页面就是纯静态页了(至少首屏是固定的)。如果将来要做动态页面,比如根据不同的人群 显示不同的内容,这种能力,将很难和CDN缓存共存。
码字不易,点赞鼓励