您现在的位置是:首页 > 创新技术
(超详细)页面性能利器:缓存
智慧创新站
2024-11-20【创新技术】25人已围观
简介缓存是一项用来提高网站性能不可或缺的技术,利用这项技术可以很好地提高web的性能。缓存可以很有效地降低网络的时延,同时也会减少大量请求对于服务器的压力。我相信你看完这篇文章后对缓存会有一个全新的认识,如果没有那就再看一遍。文章目录缓存的优点地址栏网址缓存HSTS预加载DNS缓存ARP(地址解析协议)...
缓存是一项用来提高网站性能不可或缺的技术,利用这项技术可以很好地提高web的性能。缓存可以很有效地降低网络的时延,同时也会减少大量请求对于服务器的压力。
我相信你看完这篇文章后对缓存会有一个全新的认识,如果没有那就再看一遍。

缓存的优点
地址栏网址缓存
HSTS预加载
DNS缓存
ARP(地址解析协议)缓存
TCP发送缓冲区接收缓冲区
HTTP请求缓存(CDN节点缓存、代理服务器缓存、浏览器缓存、后端动态计算结果缓存等)
缓存的优点缓存总结起来主要有以下几大优势:
减少冗余的数据传输,可节省流量
缓解带宽瓶颈问题,可更快加载页面
缓解瞬间拥塞,可缓解原始服务器的压力
降低距离延时,加快响应速度
地址栏网址缓存输入url后遇到的第一个缓存环节就是地址栏网址缓存。
但我们输入一个常用的网址时,经常会有这样的情况,我们只是输入了几个字母,浏览器就自动补全了该网址。如下图:我只输入i,浏览器就会给出相应的浏览地址:

当我们使用这个自动补全的网址时,你会发现请求的相关的静态资源也是从缓存中取得的。
转换非ASCII的Unicode字符
浏览器检查输入是否含有不是a-z,A-Z,0-9,-或者.的字符;如果有的话,浏览器会对主机名部分使用Punycode编码
检查HSTS预加载列表HSTS(HTTPStrictTransportSecurity)国际互联网工程组织IETE正在推行一种新的Web安全协议,作用是强制客户端(如浏览器)使用HTTPS与服务器创建连接。
采用HSTS后:支持这个协议的浏览器,在输入URL后会检查自带的HSTS预加载列表(这个列表里包含了那些请求浏览器只使用HTTPS进行连接的域名),若网站在这个列表里,浏览器会使用HTTPS协议并且返回码为307。而不支持HSTS的浏览器访问我们的网站,则不会产生跳转,从而提高了兼容性。这个机制对于不支持HTTPS的搜索引擎来说是非常友好的!
如掘金输入:
如果你想查看HSTS预加载列表是否存在你想访问的域名,你可以在输入chrome://net-internals/dns查找目前系统中的DNS缓存和Chrome中使用的情况。
可能涉及面试题
问:浏览器DNS缓存的时间一般不会太长,一分钟左右。为什么缓存不设置较长时间呢?
答:虽然DNS缓存可以提高获取DNS的速度,但缓存时间过长也会影响DNS在IP变更时不能及时解析到最新的IP。
ARP(地址解析协议)缓存ARP是一种用以解释地址的协议,根据通信方的IP地址就可以反查出对应方的MAC地址。
ARP缓存是个用来储存IP地址和MAC地址的缓冲区,其本质就是一个IP地址与MAC地址的对应表,表中每一个条目分别记录了其他主机的IP地址和对应的MAC地址。
当地址解析协议被询问一个已知IP地址节点的MAC地址时,先在AR缓存中查看,若存在,就直接返回与之对应的MAC地址;若不存在,才发送ARP请求查询。
具体的ARP请求查询感兴趣的同学可以自行研究。
TCP发送缓冲区接收缓冲区建立TCP连接这一步也涉及到缓存——用来临时存放双方通信的数据,保证通信数据不会丢包。
每个TCP连接在内核中都有一个发送缓冲区和接收缓冲区,TCP的全双工的工作模式以及TCP的流量(拥塞)控制便是依赖于这两个独立的buffer以及buffer的填充状态。
发送缓冲区
发送缓冲区存放的是s()方法从应用缓冲区拷贝过来的数据。
内核基本上是按照MSS(MaximumSegmentSize,最大报文段长度)从缓冲区中取数据发送出去,当缓冲区中数据小于MSS,则将剩余数据全部发送出去。TCP的发送缓冲区必须为已发送的数据保留一个副本,直到它被对端确认为止,才能从缓冲区中删掉已确认的数据。
接收缓冲区
接收缓冲区被TCP用来保存接收到的数据,直到应用程序来读取。
接收缓冲区把数据缓存入内核,等待recv()方法读取,recv()方法所做的工作,就是把内核缓冲区中的数据拷贝到应用层用户的buffer里面,拷贝后就删掉已确认的数据。
流控制(FlowControl)
TCP流控制主要用于匹配发送端和接收端的速度,即根据接收端当前的接收能力来调整发送端的发送速度。
由于发送速度可能大于接收速度,接收端的应用程序未能及时从接收缓冲区读取数据,接收缓冲区不够大不能缓存所有接收到的报文等原因,TCP接收端的接收缓冲区很快就会被塞满;从而导致不能接收后续的数据,发送端此后发送数据是无效的,因此需要流控制。
TCP的缓存就讲到这里,感兴趣的可以自己翻阅资料。
HTTP请求缓存(CDN节点缓存、代理服务器缓存、浏览器缓存等)在建立了TCP连接之后,就开始HTTP请求了;而HTTP缓存是优化性能不可忽视的一部分,这一部分我会着重讲解。
再讲具体过程之前,我再讲一遍强缓存和协商缓存。
强缓存(Cache-Control和Expires)
强缓存主要是采用响应头中的Cache-Control和Expires两个字段进行控制的。
其中Expires是中定义的,它指定了一个绝对的过期时期。而Cache-Control是时出现的缓存控制字段。由于Expires是时代的产物,因此设计之初就存在着一些缺陷,如果本地时间和服务器时间相差太大,就会导致缓存错乱。
这两个字段同时使用的时候Cache-Control的优先级会更高一点。
这两个字段的效果是类似的,客户端都会通过对比本地时间和服务器返回的生存时间来检测缓存是否可用。如果缓存没有超出它的生存时间,客户端就会直接采用本地的缓存。如果生存日期已经过了,这个缓存也就宣告失效。接着客户端将再次与服务器进行通信来验证这个缓存是否需要更新。
在请求头中使用Cache-Control时,它可选的值有:
在响应头中使用Cache-Control时,它可选的值有:
可缓存性
public:响应可以被任何对象(客户端、代理服务器等)缓存
private:只能被单个用户缓存,不能作为共享缓存
no-cache:使用缓存副本之前,需要将请求提交给原始服务器进行验证,验证通过才可以使用
only-if-cached:客户端只接受已缓存的响应,并且不向原始服务器检查是否有更新的拷贝
到期
max-age=seconds:缓存存储的最大周期,超过这个时间缓存被认为过期(单位秒)。与Expires相反,时间是相对于请求的时间
s-maxage=seconds:覆盖max-age或者Expires头,但是仅适用于共享缓存(比如各个代理),并且私有缓存中它被忽略
max-stale[=seconds]:表明客户端愿意接收一个已经过期的资源。可选的设置一个时间(单位秒),表示响应不能超过的过时时间
min-fresh=seconds:表示客户端希望在指定的时间内获取最新的响应
重新验证和重新加载
must-revalidate:缓存必须在使用之前验证旧资源的状态,并且不可使用过期资源。
proxy-revalidate:与must-revalidate作用相同,但它仅适用于共享缓存(例如代理),并被私有缓存忽略
其他
no-store:彻底得禁用缓冲,本地和代理服务器都不缓冲,每次都从服务器获取
no-transform:不得对资源进行转换或转变。Content-Encoding,Content-Range,Content-Type等HTTP头不能由代理修改。
协商缓存(Last-Modified和Etag)协商缓存机制下,浏览器需要向服务器去询问缓存的相关信息,进而判断是重新发起请求还是从本地获取缓存的资源。如果服务端提示缓存资源未改动(NotModified),资源会被重定向到浏览器缓存,这种情况下网络请求对应的状态码是304。
当客户端再次请求该资源的时候,会在其请求头上附带上If-Modified-Since字段(值就是第一次获取请求资源时响应头中返回的Last-Modified值)。如果修改时间未改变则表明资源未过期,命中缓存,服务器就直接返回304状态码,客户端直接使用本地的资源。否则,服务器重新发送响应资源,从而保证资源的有效性。
Etag和If-None-Match
基于资源校验码(一般为md5值)而验证缓存的过期机制
当客户端再次请求该资源的时候,会在其请求头上附带上If-None-Match字段(值就是第一次获取请求资源时响应头中返回的Etag值),其值与服务器端资源文件的验证码进行对比,如果匹配成功直接返回304状态码,从浏览器本地缓存取资源文件。如果不匹配,服务器会把新的验证码放在请求头的Etag字段中,并且以200状态码返回资源。
需要注意的是当响应头中同时存在Etag和Last-Modified的时候,会先对Etag进行比对,随后才是Last-Modified。
Etag的问题
相同的资源,在两台服务器产生的Etag是不同的,所以对于使用服务器集群来处理请求的网站来说,Etag的匹配概率会大幅降低。所在在这种情况下,使用Etag来处理缓存,反而会有更大的开销。
静态资源和动态资源的请求过程解析静态资源
第一次请求肯定是从服务器请求过来的资源,这个没有什么疑问,我们先看看第一次请求的响应头的内容:
我们发现第一次的响应头中包含可强缓存的相关字段cache-control,同时也包含了协商缓存的相关字段etag和last-modified;
当强缓存和协商缓存字段同时存在时会进行以下步骤来请求资源:
强缓存和协商缓存同时存在,如果强缓存还在有效期内则直接使用缓存;如果强缓存不在有效期,协商缓存生效。
即:强缓存优先级协商缓存优先级
强缓存的expires和cache-control同时存在时,cache-control会覆盖expires的效果,expires无论有没有过期,都无效。
即:cache-control优先级expires优先级。
协商缓存的Etag和Last-Modified同时存在时,Etag会覆盖Last-Modified的效果。
即:ETag优先级Last-Modified优先级。
第二次请求该资源的时候,就直接是从缓存中读取的:
其实我们第一次获取的资源极有可能是从CDN节点的缓存中获取的,也很有可能是从中间代理服务器(nginx,node等)的缓存中读取的;其中的好处不言而喻。
动态资源
由于动态资源的返回结果不一致,所以这个我们肯定不会在浏览器(中间代理服务器)缓存动态的结果。
不过这里我们可以在后端缓存一些重复率比较高的相关的计算结果。
举个例子:这里有60只股票,用户可以选择其中几只股票作为自己的股票投资池。用户选择完股票后提交,会通过相关的算法计算其预期收益效果等指标。我们知道每次计算的时间可能会比较久,所以在这步我们可以在后端将可能的组合结果先计算好缓存起来,当我们请求的时候就后端就可以直接返回已经计算好的结果给前端。至于计算结果的缓存时间也就完全由服务器控制了。
小结好了,以上就是今天介绍的全部内容,下面在一起总结以下:
缓存所具有的几大优点
地址栏网址缓存的示例及分析
HSTS预加载的表现形式
DNS缓存的流程演示及原理分析
ARP(地址解析协议)缓存的讲解
TCP发送缓冲区接收缓冲区的分析讲解
HTTP请求缓存(CDN节点缓存、代理服务器缓存、浏览器缓存、后端动态计算结果缓存等)
很赞哦!(88)