一、序言
缓存服务器是什么?
缓存在计算机系统中是用于减少处理器访问内存所需平均时间的部件。而在互联网系统中,缓存服务器是能够将用户所需要的资源不需要交由后端服务器去进行处理直接响应给用户的服务器,从而能够让用户能够更加快速的接收到资源,还能够给后端的服务器减轻负载。所以,缓存服务器在网站架构中是非常重要的一环,有着“缓存为王”的说法。
因为程序的局部性,所以导致缓存成为可能。这个局部性分为时间局部性与空间局部性
- 时间局部性:过去访问的程序在未来的时间可能会再次被访问到
- 空间局部性:一个数据被访问到了,那么离它较近的数据也可能会再次被问到
在缓存中,命中率是有效的判断缓机制是否合理的一个衡量标准。命中率又分为两种:
- 文档命中率:无论是图片还是文本文件统称为文档。从文档个数进行衡量
- 字节命中率:文档的内容很大的时候,缓存命中大量的字节。从内容大小进行衡量
而在缓存服务器中最著名的有两个软件:squid 和 varnish。squid 相当于 web 服务器领域中的 Apache,varnish 则相当于 Nginx 。这里我们主要说说 varnish 。
二、HTTP 协议中关于缓存的知识
缓存控制机制
1、Expires:基于时间控制的,表示一个内容被缓存之后的新鲜度的有效期限。这是一个固定的时间,但是可能服务器端与客户端的时间不一样,导致缓存提前失效
2、Cache-Control: 基于缓存控制,缓存控制有众多选项
请求(cache-request-directive):
no-cache:不要缓存的实体,要求现在从WEB服务器去取
max-age:只接受 Age 值小于 max-age 值,并且没有过期的对象,也就是说这个资源定义的 max-age 是三个小时,Age 是两个小时,那么这个时候客户端能够接受这个缓存的资源。但是如果 Age 变成了四个小时了,而这个时候 Age 要比 max-age 大,那么客户端就不会接受这个缓存。这个前提是缓存没有失效
max-stale:可以接受过期的对象,但是过期时间必须小于 max-stale 值。也就是这个缓存对象已经过期了,但是与后端的服务器联系不上了,所以缓存服务器将这个缓存响应给了客户端
min-fresh:接受其新鲜生命期大于其当前 Age 跟 min-fresh 值之和的缓存对象。如果 Age 是三个小时,min-fresh 是一个小时,那么能够接受这个缓存为四个小时,只要这个缓存不超过四个小时客户端都接受
响应(cache-response-directive):
public: 可以用 Cached 中内容回应任何用户;表示这是一个公共的缓存对象,谁都可以使用。 可存缓存于公共缓存中对象
private:只能用缓存内容回应先前请求该内容的那个用户,表示这是一个私有缓存,只能响应给特定用户。这也就表示用户的私有信息是可以被缓存的
no-cache:可以缓存,但是只有在跟WEB服务器验证了其有效性后,才能返回给客户端
max-age:本响应包含的对象的过期时间
no-store:不允许缓存,请求响应都可以使用的
新鲜度检测机制
对于HTTP/1.0与HTTP/1.1,有两种不同的检测机制
1、过期日期机制:
HTTP/1.0-Expires
HTTP/1.0 协议使用的是 Expires 缓存机制
Expires: Tue,17 Oct 2017 11:06:27 GMT
这是服务器指定的缓存有效期限,如果超过这个期限,则缓存失效
但是这有一个缺陷:如果客户端的时间比服务器端的时间要快,且快的时间超过了缓存时间,那么对于客户端来说,缓存永远是过期的。
Expires:-1
这是在浏览器中的响应头部查看到的。表示不缓存
HTTP/1.1-Cache-Control
HTTP/1.1 使用了Cache-Contorl机制,就是告诉客户端这个网页能够存活多长时间
Cache-Control:private, max-age=0
这是HTTP/1.2协议使用的机制,表示不缓存
2、有效性再验证:revalidate
当浏览器在访问过一个网站之后,会将其中的一些静态资源进行缓存,等到第二次使用到缓存中的资源的时候会向浏览器发送一个条件式请求
(1) 如果原始内容未发生改变,则仅响应首部(不附带body部分),响应码304(Not Modified)
(2) 如果原始内容发生改变,则正常响应,响应码为200
(3) 如果原始内容小时,则响应404,此时缓存中的cache object也应该被删除
条件式请求首部
If-Modified-Since: 基于请求内容的时间戳作验证。验证就是修改的时间戳是否一致,如果不一致那么则服务器端将最新的响应过来
注意:基于时间戳进行验证有一个缺陷,时间戳最短只能记录1s钟,如果某一个网站的页面在不到1s钟的时间发生了改变,这个时候该资源的时间戳是不会发生改变的。那么浏览器再次向服务器请求该资源是否发生了改变,那么服务