缓存介绍
缓存的优点
减少冗余的数据传输 节省流量
缓解了网络瓶颈的问题 不需高带宽即可快速加载页面
降低了对原始服务器的要求 服务器更快响应 避免过载
降低了距离时延 服务器较远 降低传输时间
什么情况下使用缓存
冗余的数据传输(GET)
带宽瓶颈
瞬间拥塞
。。。。。
缓存过程
一般缓存场景
缓存命中:客户端请求缓存 缓存将缓存的副本发送给客户端
缓存未命中:客户端请求缓存 缓存中没有对应的副本 请就被转发给客户端
缓存再验证命中:客户端请求缓存 缓存无法判断该副本是否新鲜 发送验证请求给服务端 服务器端返回仍是新鲜 缓存则将副本发送给客户端
缓存处理步骤
网络中接收抵达的请求报文
缓存对报文进行解析 提出URL和各种首部
查询本地是否有可用副本 没有就保存一份在本地
查看副本是否足够新鲜 新鲜检测
缓存会用新的首部和缓存的主题来构建报文
发送报文给客户端
日志记录事务
文档过期
Expires首部 HTTP/1.0 绝对的过期时间
Cache-Control:max-age首部 HTTP/1.1 定义文档的最大使用期,最大的合法生存时间(单位:s)
服务器再验证
文档过期了 并不代表其就不新鲜了 下一步就是服务器再验证 询问文档是否发生变化
If-Modified-Since首部
If-None-Match:tags首部
If-Modified-Since
当浏览器第一次从服务端获取数据响应为200的时候,缓存会获取Last-Modified字段。
再验证的时候,会在请求中加上If-Modified-Since字段,该字段的值就是Last-Modified字段的值。意思告诉服务端当该对象在的Last-Modified时间在If-Modified-Since之后,我的缓存不新鲜给我新鲜的。 否则我的缓存就是新鲜的不需要再提供了。
服务端一般会有三中响应:
再验证命中:对象未修改 304 Not Modified(成功的再验证比缓存未命中要快,失败的再验证几乎和未命中速度一样)
再验证未命中:对象修改了 200 OK
对象被删除:404 Not Found 缓存也会删除对应副本
If-None-Match
但是也有一些特殊情况
文档周期行重写(后台进程写入)实际包含数据一样 内容一样 但是修改日期发生变化
文档那个修改了 不过修改不重要 不需要缓存更新
有些服务器无法判断其最后修改时间
有些服务器会在亚秒间隙发生变化 对于服务器来说 以一秒为单位的粒度修改日期就不够了
这种情况 采用的方法就是打tag 加班本号
If-None-Mathc可以是多个,告诉服务器这些实体标签对应的对象均有存在缓存副本
控制缓存的能力
服务器可以通过HTTP定义的几种方式制定文档缓存多久 按照优先级
Cache-Control:public
Cache-Control:no-store
Cache-Control:no-cache
Cache-Control:must-revalidate
Cache-Control:max-age
Expires:date
不添加过期时间 让浏览器自己判断
这里no-store缓存对响应进行复制,缓存会转发响应,删除对象
no-cache实际上是可以存储在本地缓存中的,只是在于原始服务器进行新鲜验证之前 不能提供给客户端使用
Cache-Control:max-age还有一种
Cache-Control:s-maxage=3600 仅针对的是共享缓存
max-age=0则是不使用缓存 每次进入都要刷新
must-revalidate告诉缓存 在没有跟服务器进行新鲜验证的情况下 不允许提供
一个允许缓存的报文信息
一份不可以缓存的报文信息
命中率
缓存命中率:有缓存提供的请求占所有请求的比例
字节命中率:缓存字节占总字节比例
区别请求来自于缓存还是非缓存
对比响应的Date字段 如果响应的Date字段比当前时间较早 则说明来自缓存
代理与缓存
缓存的拓扑结构
私有缓存:浏览器缓存 (浏览器输入chrome://cache/查看本地缓存)
共有代理缓存:缓存代理服务器
缓存的层次结构
实际情况中通常是层次化缓存。较小缓存未命中的请求会被导向较大父缓存。
靠近客户端的地方使用较小廉价缓存,在更高层次中,则逐步采用更大,功能更强的缓存,来装载多用户共享的文档
网状缓存内容路由及对等缓存
网状缓存也叫内容路由器:代理缓存之间会议更加复杂的方式对话,做出动态的缓存通信决定,决定于那个父缓存进行通话,或者决定彻底绕开缓存,直接连接原始服务器
其包含以下功能:
根据URL在父缓存或原始服务器回见进行动态选择
根据URL动态选择一个特定的父缓存
前往父缓存之前 在本地缓存中搜索一缓存的副本
允许其他缓存对其缓存的部分进行访问 但不允许流浪访问缓存
缓存的复杂关系允许不同的组织互为对等实体,缓存共享(兄弟缓存)。HTPP不支持兄弟缓存,因此还有一些协议(HTCP)快播P2P?
总结:与缓存相关的首部字段
首部字段 | 值 | 描述 |
---|---|---|
Cache-Control | public | 响应可以被缓存(默认) |
-- | private | 响应可以被浏览器缓存 但是不允许中继缓存(CDN)缓存 |
-- | no-store | 禁止浏览器和中继缓存进行缓存 |
-- | no-cache | 浏览器可以缓存 但是未经新鲜度检查之前不能使用 |
-- | max-age | 一个以秒为单位数字,是一个相对时间。 Date+max-age则是绝对的最大过期时间。 |
Expires | date | HTTP/1.0标准的 绝对过期时间 |
Date | date | 只存在于response中 报文响应时候的时间 |
Last-Modified | date | 只存在于response中 文档最后被修改的时间 |
If-Modified-Since | date | 只存在于request中 新鲜度度检验时候需要 查询文档是否在该时刻之后修改过 如果未修改过 更新缓存的文档的Date,并且提供缓存副本 如果修改过 更新新的文档,提供新的文档 |
If-None-Match | tag | 只存在于request中 告诉服务端这些版本有对应的缓存 |
Pragma | no-cache等 | HTTP/1.0时代的首部字段 功能相当于Cache-Control |
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。