参考资料文章
https://github.com/zhangguixu/sourcecode/blob/master/network/cache.md
http://www.alloyteam.com/2016/03/discussion-on-web-caching/#prettyPhoto
http://blog.jobbole.com/30940/
http://caibaojian.com/browser-cache.html
https://kb.cnblogs.com/page/92320/
http://www.cnblogs.com/Leo_wl/p/5686610.html
缓存
全称高速缓存(英文:cache,简称缓存)其原始意义是指访问速度比一般随机存取内存(RAM)快的 一种RAM,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。(维基百科)
缓存就是数据交互的缓冲区(称作Cache),当某一硬件要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从内存中找。由于缓存的运行速度比内存快的多,故缓存的作用就是帮助硬件更快的运行。(百度百科)
总结:访问速度比一般RAM快的数据交互缓冲区
作用
总结:存储临时访问过的数据,对写入的数据进行暂时存放,缓存提高数据的读取速度
缓存分类
CPU缓存, 一级缓存, 二级缓存, 三级缓存,
超级缓存, 系统缓存, 磁盘缓存, 光驱缓存,
分布缓存, web缓存...
web缓存分类
客户端(浏览器缓存)、代理服务器、及服务器端
web缓存优点
- 减少网络流量,从而减轻拥塞。
- 降低客户访问延迟,其主要原因有:①从代理服务器获取内容从而减小了传输延迟②没有被缓存的内容由于网络拥塞及服务器负载的减轻而可以较快地被客户获取。
- 由于客户的部分请求内容可以从代理处获取,从而减轻了远程服务器负载。
- 如果由于远程服务器故障或者网络故障造成远程服务器无法响应客户的请求,客户可以从代理中获取缓存的内容副本,使得WWW服务的鲁棒性得到了加强。
web缓存缺点
- 客户通过代理获取的可能是过时的内容。
- 如果发生缓存失效,客户的访问延迟由于额外的代理处理开销而增加。因此在设计Web缓存系统时,应力求做到Cache命中率最大化和失效代价最小化。
- 代理可能成为瓶颈。因此应为一个代理设定一个服务客户数量上限及一个服务效率下限,使得一个代理系统的效率至少同客户直接和远程服务器相连的效率一样。
浏览器器缓存
浏览器缓存(BrowerCaching)是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。
页面的缓存状态是由http-header来决定的,一个服务器响应信息。Http的Cache机制总共有4个组成部分:
Cache-Control、Last-Modified(If-Modified-Since)、Etag(If-None-Match) 、Expires。
服务器响应头:Last-Modified,Etag
浏览器请求头:If-Modified-Since,If-None-Match
一、Cache-Control:
- max-age(单位为s)指定设置缓存最大的有效时间,定义的是时间长短。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。
我们来找个资源看下。比如shang.qq.com上的css资源,max-age=2592000,也就是说缓存有效期为2592000秒(也就是30天)。于是在30天内都会使用这个版本的资源,即使服务器上的资源发生了变化,浏览器也不会得到通知。max-age会覆盖掉Expires,后面会有讨论。
-
s-maxage(单位为s)同max-age,只用于共享缓存(比如CDN缓存)。
比如,当s-maxage=60时,在这60秒中,即使更新了CDN的内容,浏览器也不会进行请求。也就是说max-age用于普通缓存,而s-maxage用于代理缓存。如果存在s-maxage,则会覆盖掉max-age和Expires header。
-
public 指定响应会被缓存,并且在多用户间共享。也就是下图的意思。如果没有指定public还是private,则默认为public。
-
private 响应只作为私有的缓存(见下图),不能在用户间共享。如果要求HTTP认证,响应会自动设置为private。
-
no-cache 指定不缓存响应,表明资源不进行缓存,比如
但是设置了no-cache之后并不代表浏览器不缓存,而是在缓存前要向服务器确认资源是否被更改。因此有的时候只设置no-cache防止缓存还是不够保险,还可以加上private指令,将过期时间设为过去的时间。
no-store 绝对禁止缓存,一看就知道如果用了这个命令当然就是不会进行缓存啦~每次请求资源都要从服务器重新获取。
must-revalidate指定如果页面是过期的,则去服务器进行获取。这个指令并不常用,就不做过多的讨论了。
二、Expires
缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点。也就是说,Expires=max-age + 请求时间,需要和Last-modified结合使用。但在上面我们提到过,cache-control的优先级更高。 Expires是Web服务器响应消息头字段,在响应http请求时告诉浏览器在过期时间前浏览器可以直接从浏览器缓存取数据,而无需再次请求。
三、Last-modified
服务器端文件的最后修改时间,需要和cache-control共同使用,是检查服务器端资源是否更新的一种方式。当浏览器再次进行请求时,会向服务器传送If-Modified-Since报头,询问Last-Modified时间点之后资源是否被修改过。如果没有修改,则返回码为304,使用缓存;如果修改过,则再次去服务器请求资源,返回码和首次请求相同为200,资源为服务器最新资源。
如下图,最后修改时间为2014年12月19日星期五2点50分47秒
四、ETag
根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改,如果没有修改,过程如下:
使用ETag可以解决Last-modified存在的一些问题:
- 某些服务器不能精确得到资源的最后修改时间,这样就无法通过最后修改时间判断资源是否更新
- 如果资源修改非常频繁,在秒以下的时间内进行修改,而Last-modified只能精确到秒
- 一些资源的最后修改时间改变了,但是内容没改变,使用ETag就认为资源还是没有修改的。
浏览器请求到响应的过程
浏览器缓存分类
缓存协商,彻底缓存 又称 协商缓存和强缓存
强缓存
强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。
Expires
该字段是http1.0时的规范,它的值为一个绝对时间的GMT格式的时间字符串,比如Expires:Mon,18 Oct206623:59:59GMT。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。
Cache-Control
Cache-Control是http1.1时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对时间,例如Cache-Control:max-age=3600,代表着资源的有效期是3600秒。cache-control除了该字段外,还有下面几个比较常用的设置值:
协商缓存
协商缓存就是由服务器来确定缓存资源是否可用,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到下面两组header字段,这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段。
Last-Modify/If-Modify-Since
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间,例如Last-Modify:Thu,31 Dec 2037 23:59:59GMT。当浏览器再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。如果命中缓存,则返回304,并且不会返回资源内容,并且不会返回Last-Modify。
ETag/If-None-Match
与Last-Modify/If-Modify-Since不同的是,Etag/If-None-Match返回的是一个校验码。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据浏览器上送的If-None-Match值来判断是否命中缓存。如果Etag的值和If-None-Match的值相等,说明服务器的资源没有更新,返回304状态码,客户端直接读取缓存即可。如果Etag的值和If-None-Match的值不等,说明服务器的资源有更新,返回200状态码,不读取缓存,重新从服务器获取资源。
与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化。
浏览器页面请求
第一次
第一次请求,无论是静态文件还是其他文件,都是从服务器那里读取的。因此没有缓存之说。等第一次请求完,浏览器就有缓存了,然后整个的加载过程就完全不一样了。
浏览器再次请求
浏览器再次请求,情况就不一样了。首先会读取缓存,然后判断缓存是否过期,如果不过期,就直接读取缓存。否则,判断浏览器返回的头部信息是否存在Etag,如果存在,浏览器会像服务器发送带有If-None-Match的请求头,来和服务器返回的Etag做对比,如果if-None-Match和Etag相等。说明缓存没有更新,服务器返回304,浏览器继续从缓存读取相应的内容。如果if-None-Match和Etag不等,则服务器返回200,浏览器重新需要从服务器获取内容。
如果服务器的返回信息里面没有Etag,则判断浏览器的返回信息里是否有Last-Modified。如果有,浏览器会像服务器发送一个if-Modified-Since的请求头。然后if-Modified-Since的值会和Last-Modified的值做对比,如果if-Modified-Since的值大于等于Last-Modified,则服务器返回304,文件没有更新,直接读取缓存即可。如果if-Modified-Since
的值小于Last-Modified。则说明浏览器的缓存不是最新的,需要从服务器重新读取。如果服务器返回的头部信息既没有Etag,又没有Last-Modified,则缓存已经失效了,重新服务器抓取。
浏览器缓存优点:
- 减少了冗余的数据传输,节省了网费
- 减少了服务器的负担,大大提升了网站的性能
- 加快了客户端加载网页的速度
web(World Wide Web 互联网总称)
CND(Content Delivery Network 内容分发网络)
DNS(domain name system 域名系统)
TCP/IP(transmission control protocal/Internet protocol
传输控制协议/互联网协议)