找回密码
 会员注册
查看: 29|回复: 0

浅析HTTP缓存

[复制链接]

3

主题

0

回帖

10

积分

新手上路

积分
10
发表于 2024-10-1 17:32:27 | 显示全部楼层 |阅读模式
已关注 关注 重播 分享 赞 关闭观看更多更多字节前端 ByteFE已关注分享点赞在看已同步到看一看写下你的评论分享视频,时长09:220/000:00/09:22 切换到横屏模式 继续播放进度条,百分之0播放00:00/09:2209:22 倍速播放中 0.5倍 0.75倍 1.0倍 1.5倍 2.0倍 超清 流畅 您的浏览器不支持 video 标签 继续观看 浅析HTTP缓存 观看更多转载,浅析HTTP缓存字节前端 ByteFE已关注分享点赞在看已同步到看一看写下你的评论 视频详情 1. 为什么需要缓存通过缓存机制,可以在相应场景下复用以前获取的资源。显著提高网站的性能和响应速度减少网络流量和等待渲染时间降低服务器压力2. HTTP 缓存类型强缓存协商缓存3. 强缓存对于强缓存,服务器返回的静态资源响应头会设置一个强制缓存的时间,在缓存时间内,如刷新浏览器请求相同资源,在缓存时间未过期的情况下,则直接使用已缓存资源。如缓存资源已过期,执行协商缓存策略。以下为与强缓存相关的 HTTP 头部字段3.1 Expires响应头Expires字段包含强缓存资源的过期时间值为 0 表示资源已过期或非强缓存3.2 Cache-Control通用消息头字段,通过指令来实现缓存机制。说明一下容易弄混的两个字段,其他指令参考指令大全[1]。no-cache在发布缓存副本之前,强制要求缓存把请求提交给原始服务器进行验证(协商缓存验证)。no-store缓存不应存储有关客户端请求或服务器响应的任何内容,即不使用任何缓存。3.3 Expires 和 Cache-Control 的区别时间区别Expires 过期时间为绝对时间,指未来某个时间点缓存过期。Cache-Control 为相对时间,相对于当前时间,如 60s 后缓存过期优先级Expires 的优先级低于 Cache-Control 字段同时存在 Cache-Control 和 Expires时,以 Cache-Control 指令为准HTTP 版本Expires 是 HTTP/1.0 提出的,其浏览器兼容性更好Cache-Control 是 HTTP/1.1 提出的,浏览器兼容性不佳,所以 Expires 和 Cache-Control 可以同时存在,在不支持 Cache-Control的浏览器则以Expires为准4. 协商缓存协商缓存即和服务器协商是否使用缓存,通过判断后决定重新加载资源 or HTTP StatusCode 304以下字段决定是否使用协商缓存,而非强缓存:4.1 PragmaPragma是一个 HTTP1.0 中规定的通用首部,如果Cache-Control不存在的话,它的行为与Cache-Control: no-cache一致。强制要求缓存服务器在返回缓存的版本之前将请求提交到源头服务器进行协商验证。Pragma 的值就只有一个,no-cache,并且它的优先级比 Cache-Control 高。4.2 Cache-Control上文介绍过Cache-Control,它的指令既可以用于强缓存又可应用于协商缓存策略中其中Cache-Control: no-cache 和 Cache-Control: max-age=0 的作用一样,强制要求发起请求给服务器进行验证 (协商资源验证)。5. 协商策略当出现Pragma字段或者Cache-Control:no-cache时,就需要使用协商策略,常见的两对协商缓存字段如下ETag/If-None-MatchLast-Modified/If-Modfied-Since优缺点如果服务端修改了一段代码,然后又改回去了。此时资源文件的修改时间变了实际上文件没有发生改变这样缓存就失效了,产生了不必要的传输而 ETag 可以根据内容生成的 hash 来比较的,只要资源文件内容不变,就会应用客户端的缓存,减少不必要的传输。所以 ETag 比 Last-Modified 缓存更精确、高效和节省带宽。6. ETag6.1 什么是 ETag?Etag 是 Entity tag 的缩写,可以理解为“被请求资源的摘要标识”,Etag 是服务端的一个资源的标识,在 HTTP 响应头中将其传送到客户端,类似这样,ETag:W/"50b1c1d4f775c61:df3"6.2 ETag 格式ETag:W/"xxxxxxxx"ETag:"xxxxxxx"强类型验证比对资源每个字节都要一样。W/前缀代表使用弱类型验证不需要每个字节都一样,例如页脚的时间 or 展示的广告不一样,都可以认为是一样的。构建应用于弱验证类型的标签(etag)体系可能会比较复杂,因为这会涉及到对页面上不同的元素的重要性进行排序,但是会对缓存性能优化相当有帮助。6.3 ETag 生成需要满足什么条件?当文件更改时,ETag 值必须改变尽量便于计算,不会特别耗 CPU。利用摘要算法生成(MD5, SHA128, SHA256)需慎重考虑,这些为 CPU 密集型运算。不是不能用。没有最好的算法,只有适合对应场景的算法。必须横向扩展,分布式部署时多个服务器节点上生成的 ETag 值保持一致。6.4 ETag 是怎么生成的(Nginx)Nginx[2]的源码中 ETag 由 last_modified 和 content_length 拼接而成etag->value.len=ngx_sprintf(etag->value.data,"\"%xT-%xO\"",r->headers_out.last_modified_time,r->headers_out.content_length_n)-etag->value.data;翻译为以下伪代码etag=header.last_modified+"-"+header.content_lenth总结:Nginx 中 ETag 由响应头的Last-Modified和Content-Length表示为十六进制组合而成。Lodash 网站请求检验constLAST_MODIFIED=newDate(parseInt('5fc4907d',16)*1000).toJSON()constCONTENT_LENGTH=parseInt('f48',16)console.log(LAST_MODIFIED)//2020-11-30T06:26:05.000Zconsole.log(CONTENT_LENGTH)//3912输出结果既然在nginx中ETag由Last-Modified和Content-Length组成,那它便算是一个加强版的Last-Modified了,那加强在什么地方呢?Last-Modified只能作用于秒级的改变,而 nginx 中的 ETag 添加了文件大小的附加条件,不仅和修改时间有关,也和内容有关,使之更加精确。6.5 Last-Modified 是怎么生成的在 linux 中mtime:modified time指文件内容改变的时间戳ctime:change time指文件属性改变的时间戳,属性包括mtime。而在 windows 上,它表示的是creation time而 HTTP 服务选择Last-Modified时一般会选择mtime,表示文件内容修改的时间,来兼容 Windows 和 Linux。以下为nginx 源码[3]r->headers_out.status=NGX_HTTP_OK;r->headers_out.content_length_n=of.size;r->headers_out.last_modified_time=of.mtime;6.6 如果 http 响应头中 ETag 值改变了,是否意味着文件内容一定已经更改?不一定文件在一秒内发生了改变而且文件大小不变这种情况非常极端,概率很低因此在正常情况下可以容忍一个不太完美但是高效的算法。参考资料[1]https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control[2]https://github.com/nginx/nginx/blob/6c3838f9ed45f5c2aa6a971a0da3cb6ffe45b61e/src/http/ngx_http_core_module.c#L1582[3]https://github.com/nginx/nginx/blob/4bf4650f2f10f7bbacfe7a33da744f18951d416d/src/http/modules/ngx_http_static_module.c#L217
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-12 22:03 , Processed in 1.189377 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表