计算机网络基础——HTTP缓存机制

Web缓存

Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。

浏览器缓存也包含很多内容: HTTP 缓存、indexDB、cookie、localstorage 等等。这里我们只讨论 HTTP 缓存相关内容。

在具体了解 HTTP 缓存之前先来明确几个术语:

缓存命中率:从缓存中得到数据的请求数与所有请求数的比率。理想状态是越高越好。
过期内容:超过设置的有效时间,被标记为“陈旧”的内容。通常过期内容不能用于回复客户端的请求,必须重新向源服务器请求新的内容或者验证缓存的内容是否仍然准备。
验证:验证缓存中的过期内容是否仍然有效,验证通过的话刷新过期时间。
失效:失效就是把内容从缓存中移除。当内容发生改变时就必须移除失效的内容。

浏览器缓存主要是 HTTP 协议定义的缓存机制。HTML meta 标签,例如

<META HTTP-EQUIV="Pragma" CONTENT="no-store">

含义是让浏览器不缓存当前页面。但是代理服务器不解析 HTML 内容,一般应用广泛的是用 HTTP 头信息控制缓存

HTTP缓存请求相应头

1.Cache-Control
请求/响应头,缓存控制字段,可以说是控制http缓存的最高指令,要不要缓存也是它说了算。

它有以下常用值

  • no-store:所有内容都不缓存。
  • no-cache:缓存,但是浏览器使用缓存前,都会请求服务器判断缓存资源是否是最新,它是个比较高贵的存在,因为它只用不过期的缓存
  • max-age=x(单位秒) 请求缓存后的X秒不再发起请求,属于http1.1属性,与下方Expires(http1.0属性)类似,但优先级要比Expires高。
  • s-maxage=x(单位秒) 代理服务器请求源站缓存后的X秒不再发起请求,只对CDN缓存有效(这个在后面会细说)。
  • public 客户端和代理服务器(CDN)都可缓存
  • private 只有客户端可以缓存。

2.Expires
响应头,代表资源过期时间,由服务器返回提供,GMT格式日期,是http1.0的属性,在与max-age(http1.1)共存的情况下,优先级要低。
3.Last-Modified
响应头,资源最新修改时间,由服务器告诉浏览器。
4.if-Modified-Since
请求头,资源最新修改时间,由浏览器告诉服务器(其实就是上次服务器给的Last-Modified,请求又还给服务器对比),和Last-Modified是一对,它两会进行对比。
5.Etag
响应头,资源标识,由服务器告诉浏览器。
6.if-None-Match
请求头,缓存资源标识,由浏览器告诉服务器(其实就是上次服务器给的Etag),和Etag是一对,它两会进行对比。

扫描二维码关注公众号,回复: 8548883 查看本文章

HTTP缓存方案

1.md5/hash缓存

通过为静态文件添加MD5或者hash标识,解决浏览器无法跳过缓存过期时间主动感知文件变化的问题。

为什么这么做?实现原理是什么?

我们前面说的http缓存方案,服务器与浏览器的文件修改时间对比,文件内容标识对比,前提基础都是建立在两者文件路径完全相同的情况下。

module/js/a-hash1.js与module/js/a-hash2.js是两个完全不同的文件,假想浏览器第一次加载页面,请求并缓存了module/js/a-hash1.js,第二次加载,文件指向变成了module/js/a-hash2.js,浏览器会直接重新请求a-hash2.js,因为这就是两个完全不同的文件,哪里还有什么http缓存文件对比,通过这种做法,我们就可以从根本上解决过期时间没到浏览器无法主动请求服务器的问题。因此我们只需要在项目每次发布迭代将修改过的静态文件添加不同的MD5或hash标识就好啦。

注意,这里不推荐缓存html文件,这样每次html加载渲染都可以感知文件变化,反正文件没变还是使用本地缓存,文件名都变了说明修改过,重新请求缓存就好了。

2.CDN缓存

了解CDN缓存,先得知道什么是CDN。
CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。

假设多年前我们所在的城市只有一个火车站,每次春运,整个城市的人都得去这个火车站买票,人流量以及购票的需求可想而知有多大,为了缓解这个问题,城市的不同区,都出现了火车票代售点,这样每个区的人都可以就近买票了,火车站总站的压力就这样大大减轻了。

我们可以把每个区的售票点称之为CDN节点,也就是前面所说的代理服务器。简而言之,我们可以把CDN理解成浏览器与服务器之间的临时站点,它会替服务器处理一部分的浏览器请求,从而整理减轻总服务器的压力。

我们可以把CDN的价值归纳为:

  1. CDN通过分流的形式,大大减轻源站的访问压力。
  2. 就像住的区比较偏远,每次买票要去城市中心,而这个区后来有了分站,火车票就可以就近购买一样。CDN也解决了跨地区访问问题,根本上为访问提供了加速。

CDN边缘节点缓存数据,当浏览器请求,CDN将代替源站判断并处理此处请求。

日常请求对话

第一次请求

浏览器:服务器老哥,我需要a.js.

服务器:(恼羞成怒)文件我给我小弟CDN了,以后你要这个找CDN,别找我了。成功返回a.js给CDN,CDN进行缓存,同时CDN返回给浏览器,浏览器自己也进行了缓存(cache-control的值public就是用在这的)。

后续请求…

浏览器:服务器,我缓存时间到了,赶紧给我对比下文件,看看要不要重新返回给我。

CDN节点:打住打住,叫唤啥呢,我大哥比较忙,文件给我看看,请求被代理了。

情况1:CDN节点自己缓存的文件未过期,于是返回了304给浏览器,打回了这次请求。

情况2:CDN节点发现自己缓存的文件过期了,为了保险起见,自己发起请求给了服务器(源站),成功拿回了最新数据,然后再交给与了浏览器。

其实说到这,CDN缓存的问题也跟前面的http缓存一样,CDN缓存时间不过期,浏览器始终被拦截,无法拿到最新的文件。

但是我们回归http缓存问题本质,缓存本身针对于更新频率不高的静态文件,其次,CDN缓存提供了分流以及访问加速其它优势条件。这里我问过同学,得到的信息是,CDN类似一个平台,是可以通过登录,手动更新CDN缓存的,变相解决了浏览器缓存无法手动控制的问题。

强缓存与协商性缓存(弱缓存)

强缓存:不发起http请求,直接使用本地缓存,比如浏览器地址栏回车,使用浏览器的刷新按钮,在Expires或max-age生效的情况下,触发的都是强缓存。(max-age是http1.1的属性,Expires是http1.0的属性,为了做到向下兼容,一般写两个。但如在1.1环境下,max-age优先级比Expires高。)

协商性缓存(弱缓存):在使用本地缓存前,先与服务器协商,核对缓存文件是否为最新。比如设置了cache-control=no-cache,不管你做任何操作,都会发起请求,这一类就是协商性缓存了。

发布了364 篇原创文章 · 获赞 324 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/No_Game_No_Life_/article/details/103825345