聚焦Java性能优化 打造亿级流量秒杀系统【学习笔记】05_查询性能优化技术之页面静态化
文章目录
6-1 静态资源CDN引入
静态请求CDN
用户将静态资源数据请求到ECS服务器
,ECS服务器解析到阿里云的CDN中,CDN可以理解为一个无限大的内容磁盘缓存,本身没有文件存储。当用户访问getItem的一个静态资源文件的时候,会根据路由规则查看本地是否有这样的文件,如果有直接返回,没有就回源到源站,回源到下面的OSS
中获取静态资源文件。
CDN一边返回对应的文件,一边将文件按照http指示的生命周期缓存起来,以便下次用户访问时,直接返回。
整个项目的架构:
6-3 Cache Control响应头
Cache Control状态标志着缓存的策略
- private:客户端可以缓存
- public:客户端和代理服务器都可以缓存(代理服务器指的是从客户端到服务器经过所有的中间服务器结点,比如nginx,CDN,正向代理服务器等)
- max-age=xxx:缓存的内容将在xxx秒后失效
- no-cache:强制向服务端再验证一次(客户端缓存在本地,下次使用缓存时要向服务器请求验证是否可以使用缓存)
- no-store:不缓存请求的任何返回内容
客户端向服务器验证是如何做的呢?
有效性判断
-
ETag:资源唯一标识
将请求进行MD5或Hash的加密,生成一串资源唯一标识符。
下一次请求时,发送HTTP请求带上ETag,与服务器本地关于ETag做验证,符合就返回
状态码304(Not Modified)
,表示缓存客户端可以直接使用 -
If-None-Match:客户端发送的匹配Etag标识符
-
Last-modified:资源最后被修改的时间
-
If-Modified-Since:客户端发送的匹配资源最后修改时间的标识符
整个客户端向浏览器请求流程如下:
首先用户请求资源,
1)先判断URL本地是否有缓存,如果没有直接向服务器请求,然后返回;
2)如果有,判断缓存是否过期(max-age),没有过期,直接使用缓存资源;
3)如果有max-age但过期,则优先判断ETag:有的话向服务器请求If-None-Match,请求带上ETage;
4)没有ETag,判断是否有Last-Modified,然后向服务器请求If-modified-since(客户端发送的匹配资源最后修改时间如果早于资源修改时间Last-Modified,则无效已经被修改,如果晚于则有效)
5)服务器返回的是304表示资源没有修改,则本地缓存可直接使用;如果返回200,表示资源被修改,向服务器发起请求;
6-4 浏览器三种刷新方式
-
回车刷新或a标签连接:看cache-control对应的max-age是否仍然有效,有效就直接使用本地缓存,如果cache-control中为no-cache,则进入
缓存协商逻辑
(指判断ETage或LastModified这种方式) - F5刷新或command+R刷新:去掉cache-control中的max-age或直接设置max-age为0,然后进入缓存协商逻辑
- 强制刷新ctrl+F5或command+shift+R刷新:去掉cache-control和协商头(带ETage或Last-Modified),强制刷新,从服务器获取资源
缓存协商机制:比较last-modified和ETag到服务端,若服务端判断没变化则304不返回数据,否则200返回数据
6-5 CDN自定义缓存策略
- 可自定义目录过期时间(CDN自身向源站OSS做回源的时间)
- 可自定义后缀名过期时间(针对不同后缀名设置过期时间)
- 可自定义对应权重(设置用自定义后缀名过期时间/自定义目录过期时间二者使用的权重)
- 可通过界面或api强制cdn对应目录刷新(不一定保证成功)
阿里云CDN的缓存策略这篇文章讲的很详细
6-6 静态资源cdn部署策略
部署策略一
如果静态资源文件(css,js,img)文件名不变,采用max-age缓存时间设置后,如果在缓存有效时间内发生版本更新,比如重大故障或更新,如果全都是让用户来手动刷新浏览器,清缓存,这样体验不好,有以下几种部署策略:
- css,js,img等元素使用带版本号部署,例如a.js?v=1.0不便利,且维护困难(如果单纯改某个文件版本,其他文件是否更新版本号会难以维护)
html内嵌css,js,img这些资源,必须设置成no-cache
,向服务器做缓存协商机制。html一般采用强推的概念,可以设置max-age,但每次请求都会让CDN全部失效,然后回源,这样将max-age设置一个短的时间后,用户就有版本更新
- css,js,img等元素使用带摘要部署:例如a.js?v=45edw存在先部署html还是先部署资源的覆盖问题;
给资源文件名后加一个部署摘要(一段字符串,如果文件没变化,摘要也不改变),但会存在问题。
1) 情况1-先部署资源文件后部署html
某个js文件发生变化,更改摘要后如果js先部署,js会覆盖老版本,此时html引用的还是*s,有可能导致不兼容问题;
2) 情况2-先部署html后部署资源文件
先部署html会引用新的js,而此时服务器还是老的js等,容易出错
- (推荐)css,js,imh等元素使用摘要做文件名部署,例如45edw.js,新老版本并存,且可回滚,资源部署完成后再部署html;
部署策略二
- 对应静态资源保持生命周期内不会变,max-age可设置的很长,无视失效更新周期
- html文件设置no-cache或者较短的max-age,以便于更新
- html文件仍然设置较长的max-age,依靠动态的获取版本号请求发送到后端,异步下载最新的版本号的html后展示渲染在前端
- 动态请求也可以静态化成json资源推送到cdn上;
- 依靠异步请求获取后端节点对应资源状态做紧急下架处理;
- 可通过跑批仅仅推送cdn内容使其下架等操作;
6-7 全页面静态化
html,css,js静态资源cdn化 -->js ajax动态请求cdn化(将请求变成静态文件发送到cdn)–>全页面静态化
定义:在服务端完成html,css,甚至js的load渲染成纯html文件后直接以静态资源的方式部署到cdn上
phantomjs
首先phantomjs是一个无头浏览器,可以借助其模拟webkit js 的执行
- 修改需要全页面静态化的实现,采用initView和hasInit方式防止多次初始化
- 编写对应轮询生成内容方式
- 将全静态化页面生成后推送到cdn
总结:经过全页面静态化以后,从以前刷新ajax请求填充到html这个过程变成了已经执行好的静态html页面