1. web缓存的类型在本片文章中,将阅读到的内容有:
- web缓存的类型
1.1数据库数据缓存
1.2 服务器端缓存
1.2.1 代理服务器缓存
1.2.2 CDN缓存
1.2.3 DNS缓存
1.3 浏览器端缓存
1.3.1 浏览器缓存(http缓存)
1.3.2 HTML5离线应用缓存
1.4 web应用层缓存- 浏览器缓存
- CDN缓存
- DNS缓存
本小节对大概的类型进行一个分类,剩下的篇幅会选取部分内容进行详细的介绍。
1.1数据库数据缓存
Web应用,特别是SNS类型的应用,往往关系比较复杂,数据库表繁多,如果频繁进行数据库查询,很容易导致数据库不堪重荷。为了提供查询的性能,会将查询后的数据放到内存中进行缓存,下次查询时,直接从内存缓存直接返回,提供响应效率。比如常用的缓存方案有memcached等。
1.2 服务器端缓存
1.2.1 代理服务器缓存
代理服务器是浏览器和源服务器之间的中间服务器,浏览器先向这个中间服务器发起Web请求,经过处理后(比如权限验证,缓存匹配等),再将请求转发到源服务器。代理服务器缓存的运作原理跟浏览器的运作原理差不多,只是规模更大。可以把它理解为一个共享缓存,不只为一个用户服务,一般为大量用户提供服务,因此在减少相应时间和带宽使用方面很有效,同一个副本会被重用多次。常见代理服务器缓存解决方案有 Squid等。
1.2.2 CDN缓存
CDN(Content delivery networks, 即内容分发网络。)缓存,也叫网关缓存、反向代理缓存。CDN缓存一般是由网站管理员自己部署,为了让他们的网站更容易扩展并获得更好的性能。**浏览器先向CDN网关发起Web请求,网关服务器后面对应着一台或多台负载均衡源服务器,会根据它们的负载请求,动态将请求转发到合适的源服务器上。**虽然这种架构负载均衡源服务器之间的缓存没法共享,但却拥有更好的处扩展性。从浏览器角度来看,整个CDN就是一个源服务器。
1.2.3 DNS缓存
1.3 浏览器端缓存
1.3.1 浏览器缓存(http缓存)
1.3.2 HTML5离线应用缓存
本篇对这个内容就不进行详细的介绍,可以参考这篇文章。
https://www.cnblogs.com/xiaotaiyangye/p/10910353.html
1.4 web应用层缓存
2.1 什么是浏览器缓存
浏览器缓存就是把一个已经请求过的web资源(如html页面,图片,JS,数据)拷贝一份放在浏览器中。缓存会根据进来的请求保存输入内容的副本。当下一个请求到来的时候,如果是相同的URL,浏览器会根据缓存机制决定是直接使用副本响应访问请求还是向源服务器再次发起请求。
浏览器缓存还分为强缓存和协商缓存。
2.2 强缓存
强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间。
2.2.1 Expires
该字段是http1.0时的规范,它的值为一个绝对时间的GMT格式的时间字符串,比如
Expires:Mon,18 Oct 206623:59:59 GMT。
这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。
2.2.2 Cache-Control
Cache-Control是http1.1时出现的header信息,主要是利用该字段的max-age值来进行判断,它是一个相对时间,比如
Cache-Control:max-age=3600
代表着资源的有效期是3600秒。
cache-control除了该字段外,还有下面几个比较常用的设置值:
no-cache不使用本地缓存。需要使用协商缓存,先与服务器确认返回的响应是否被更改,如果之前的响应中存在ETag,那么请求的时候会与服务端验证,如果资源未被更改,则可以避免重新下载。
no-store直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
public可以被所有的用户缓存,包括终端用户和CDN等中间代理服务器。
private只能被终端用户的浏览器缓存,不允许CDN等中继缓存服务器对其缓存。
Cache-Control与Expires可以在服务端配置同时启用,同时启用的时候Cache-Control优先级高
2.3 协商缓存
协商缓存就是由服务器来确定缓存资源是否可用,所以客户端与服务器端要通过某种标识来进行通信,从而让服务器判断请求资源是否可以缓存访问,这主要涉及到下面两组header字段,这两组搭档都是成对出现的,即第一次请求的响应头带上某个字段(Last-Modified或者Etag),则后续请求则会带上对应的请求字段(If-Modified-Since或者If-None-Match),若响应头没有Last-Modified或者Etag字段,则请求头也不会有对应的字段。·
2.3.1 Last-Modify/If-Modify-Since
浏览器第一次请求一个资源的时候,服务器返回的header中会加上Last-Modified,Last-Modified是一个时间,标识该资源的最后修改时间,例如
Last-Modified: Thu,31 Dec 2037 23:59:59 GMT
当浏览器再次请求该资源时,request的请求头中会包含If-Modified-Since,该值为缓存之前返回的Last-Modified。服务器收到If-Modified-Since后,根据资源的最后修改时间判断是否命中缓存。
如果命中缓存,则返回304,并且不会返回资源内容,并且不会返回Last-Modified。
2.3.2 ETag/If-None-Match
与Last-Modified/If-Modified-Since不同的是,Etag/If-None-Match返回的是一个校验码。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据浏览器发送的If-None-Match值来判断是否命中缓存。
与Last-Modified不一样的是,当服务器返回304 Not Modified的响应时,由于ETag重新生成过,response header中还会把这个ETag返回,即使这个ETag跟之前的没有变化。
HTTP1.1中Etag的出现主要是为了解决几个Last-Modified比较难解决的问题:
- 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
- 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
- 某些服务器不能精确的得到文件的最后修改时间。
- Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
2.4 强缓存 vs 协商缓存
2.5 浏览器缓存的优点
- 减少了冗余的数据传输,节省了网费
- 减少了服务器的负担,大大提升了网站的性能
- 加快了客户端加载网页的速度
2.6 用户行为对缓存的影响
用户在浏览器上的一些操作,会导致缓存受到影响。
2.6.1. 在地址栏中输入网址后按回车或点击转到按钮
浏览器以最少的请求来获取网页的数据,浏览器会对所有没有过期的内容直接使用本地缓存,从而减少了对浏览器的请求。所以,Expires,max-age标记只对这种方式有效。
2.6.2. 按F5或浏览器刷新按钮
浏览器会在请求中附加必要的缓存协商,但不允许浏览器直接使用本地缓存,它能够让 Last-Modified、ETag发挥效果,但是对Expires无效。
2.6.3. 按Ctrl+F5或按Ctrl并点击刷新按钮
这种方式就是强制刷新,总会发起一个全新的请求,不使用任何缓存。
2.7 实际问题运用
代码更新到线上后用户浏览器不能自行更新,我们不能要求客户在系统更新后都进行一次缓存清理的操作。到底该如何解决呢?
在资源请求的URL中增加一个参数,比如:js/mian.js?ver=0.7.1。这个参数是一个版本号,每一次部署的时候变更一下,当这个参数变化的时候,强缓存都会失效并重新加载。这样一来,静态资源,部署以后就需要重新加载。这样就比较完美的解决了问题。
3. CDN缓存3.1 什么是CDN缓存
CDN是指内容分发网络。各地部署多套静态存储服务,本质上是空间换时间,自动选择最近的节点内容,不存在再请求原始服务器,适合存储更新很少的静态内容,文件更新慢。
3.2 CDN缓存使用场景
在没有CDN的情况下
用户在浏览网站的时候,浏览器能够在本地保存网站中的图片或者其他文件的副本,这样用户再次访问该网站的时候,浏览器就不用再下载全部的文件,减少了下载量意味着提高了页面加载的速度。
在有CDN的情况下
客户端浏览器先检查是否有本地缓存是否过期,如果过期,则向CDN边缘节点发起请求,CDN边缘节点会检测用户请求数据的缓存是否过期,如果没有过期,则直接响应用户请求,此时一个完成http请求结束;如果数据已经过期,那么CDN还需要向源站发出回源请求(back to the source request),来拉取最新的数据。
下图是一个比较典型的CDN缓存的应用。
4.1 什么是DNS
全称 Domain Name System ,即域名系统。
通过域名,最终得到该域名对应的IP地址的过程叫做域名解析(或主机名解析)
有dns的地方,就有缓存。浏览器、操作系统、Local DNS、根域名服务器,它们都会对DNS结果做一定程度的缓存。
DNS查询过程如下:
- 首先搜索浏览器自身的DNS缓存,如果存在,则域名解析到此完成。
- 如果浏览器自身的缓存里面没有找到对应的条目,那么会尝试读取操作系统的hosts文件看是否存在对应的映射关系,如果存在,则域名解析到此完成。
- 如果本地hosts文件不存在映射关系,则查找本地DNS服务器(ISP服务器,或者自己手动设置的DNS服务器),如果存在,域名到此解析完成。
- 如果本地DNS服务器还没找到的话,它就会向根服务器发出请求,进行递归查询。
参考文章:
https://blog.csdn.net/toumingyumaohuiyi/article/details/52763989
https://blog.csdn.net/qq_40968685/article/details/109507853?utm_source=app&app_version=4.16.0
https://blog.csdn.net/qq_41807489/article/details/90266230
https://www.cnblogs.com/iceflorence/p/8905825.html



