学而时习之网络篇: 又是HTTP缓存的锅 !
Posted 20K+
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学而时习之网络篇: 又是HTTP缓存的锅 !相关的知识,希望对你有一定的参考价值。
给 20K+ 加星标, 助力 20K+
0
前言
春来了, 万物复苏, 阳光明媚, 一处农家院子前的空地上, 小小的藤椅上挤着一个 葛优躺的胖子, 远远看过去他那像极了游泳圈的小肚子上还放着一台 MacBook Pro 笔记本, 凑近了看笔记本屏幕上开着一个叫 码云企业版 的网站, 上面满屏都是 一位叫 Yuki 的测试妹子 指给名为 张大胖的 bug。
春日 【朝代】宋 胜日寻芳泗水滨,无边光景一时新。
等闲识得东风面,万紫千红总是春。
1
奠定互联网时代的基石
2019年1月30日 We Are Social&Hootsuite联合发布了2019年数字报告,报告显示,全球人口数76.76亿人,其中手机用户51.1亿人,网民43.9亿人,有34.8亿人活跃在社交媒体上。报告还显示,全球互联网用户平均每天上网时间为6小时42分钟,也就是人们生活中1/4的时间都在上网。这一数字略低于去年的6小时49分钟。
服务端
热点数据缓存 (ps:缓存雪崩) / Redids, Memcached
进程缓存 (ps:缓存共享麻烦) / Ehcache, Guave Cache, Hibernate
DNS&CDN网络缓存 (ps:自建维护贵) / Squid , 云计算
客户端
HTTP缓存 (ps:容易被测试找bug) / HTTP协议+nginx&Tomcat
数据预缓存 (ps:局限于微信小程序) / 周期性更新&数据预拉取
内存&本地缓存(ps: 需要管理维护) / Vuex, LocalStorage&SessionStorage
2
奠定互联网时代的基石
首先是在浏览器端, 如果是按 Ctrl+F5 组合键刷新页面, 那么浏览器会直接向目标 URL 发送请求, 而不会使用浏览器缓存的数据。
其次访问到达 URL 的 CDN 缓存服务器 也会MISS掉 再向服务器发起请求。
如果 HTTP请求的 URL 存在热点数据缓存那就无解了. 返回热点数据缓存.
所以说 客户端与服务器之间的协议级缓存, 必然通过HTTP来控制。
下图所示 当我们使用 Ctrl+F5强制刷新一个页面时, 在HTTP请求头中会增加一些新请求头.来告诉服务器我们要获取的是最新数据而不是HTTP协议缓存.
3
HTTP缓存的两大阵营
服务端告知客户端缓存存活时间后,由客户端判断并决定是否使用HTTP缓存。
由服务端决定并告知客户端是否使用缓存。
4
各类HTTP缓存的特点以及应用场景
强缓存(HTTP标准)
Cache-Control(HTTP1.1)&Pragma(HTTP1.0)
Expires (HTTP1.0)
协商缓存
Last-Modifiy/if-Modify-Since(HTTP1.1)
ETag/if-None-Match(HTTP1.1)
Pragma: no-cache是为了兼容 HTTP1.0 ,Cache-Control: no-cache 是 HTTP 1.1提供的, 个人认为 Pragma 字段为上古时期的设计Bug, 两者相辅相成用于指定所有缓存机制在整个请求/响应链中必须服从的命令, 不仅可以控制浏览器缓存还可以控制代理服务器,CDN服务器等
Exprires 的值为响应头返回的数据到期时间 Expires: Sat, 25 Feb 2020 18:26:17 GMT , 当浏览器再次请求时的请求时间小于之前返回的 Exprires 时间,则直接使用缓存数据。但由于服务端时间和客户端时间可能有误差,这也将导致缓存命中的误差.
服务器在响应请求时,会在响应头上 用 Last-Modified 告诉浏览器资源的最后修改时间. 例: last-modified: Thu, 14 Nov 2019 04:56:25 GMT , 浏览器再次请求服务器的时候,请求头会包含此字段,后面跟着在缓存中获得的最后修改时间。服务端收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回304和响应报文头,浏览器只需要从缓存中获取信息即可。从字面上看,就是说:从某个时间节点算起,是否文件被修改了.
如果真的被修改:那么开始传输响应一个整体,服务器返回状态码:200 OK
如果没有被修改:那么只需传输响应header,服务器返回状态码:304 Not Modified
Etag:服务器响应请求时,通过此字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定) If-None-Match:再次请求服务器时,浏览器的请求报文头部会包含此字段,后面的值为在缓存中获取的标识。服务器接收到次报文后发现If-None-Match则与被请求资源的唯一标识进行对比。
不同,说明资源被改动过,则响应整个资源内容,返回状态码200。相同,说明资源无修改,则响应header,浏览器直接从缓存中获取数据信息。返回状态码304.但是实际应用中由于Etag的计算是使用算法来得出的,而算法会占用服务端计算的资源,所有服务端的资源都是宝贵的,所以就很少使用Etag了。
强验证器要求文档的每个字节都相等,
而弱验证器只要求文档的含义相等
-
浏览器地址栏中写入URL,回车 浏览器发现缓存中有这个文件了,不用继续请求了,直接去缓存拿。(最快) -
F5就是告诉浏览器,别偷懒,好歹去服务器看看这个文件是否有过期了。于是浏览器就战战兢兢的发送一个请求带上If-Modify-since。 -
Ctrl+F5 告诉浏览器,你先把你缓存中的这个文件给我删了,然后再去服务器请求个完整的资源文件下来。于是客户端就完成了强行更新的操作. -
If-None-Match的生效优先级比If-Modified-Since高,所以两者同时存在时,遵从前者。
5
HTTP缓存最佳实践
不同业务对缓存要求就不同, 有的网站随机更新页面就选用强缓存, 有的网站定时更新页面就用协商缓存, 有的网站为了兼容性两种缓存都用, 亲爱的读者们, 笔者布置个作业, 下面这些网站document都用了 那些HTTP缓存技术呢 ?
-
www.zhihu.com/hot -
mp.weixin.qq.com/s/FlZXj4kk_hfqeyEIYdyXGA -
www.taobao.com
资料参考
-
深入分析 Java Web 技术内幕 -
掘金社区 <浅谈HTTP缓存> -
掘金社区 <HTTP----HTTP缓存机制>
深入浅出分享 Java 干货 , 找回对代码的 Passion , 助力月入 20K+ , 点击在看即可帮助更多人.
以上是关于学而时习之网络篇: 又是HTTP缓存的锅 !的主要内容,如果未能解决你的问题,请参考以下文章