《HTTP权威指南》笔记:第七章-缓存

一、命中和未命中缓存

使用缓存的副本为到达缓存的请求提供服务被称为缓存命中(cache hit),如果没有已缓存的副本提供,而将请求转发给源服务器,被称之为缓存未命中(cache miss)

1.1 再验证

WEB缓存对已缓存的副本进行“新鲜度检测”,会向源服务器发送一个小的再验证请求,如果缓存仍然“新鲜有效”,那么服务器会返回一个304 not modified,然后缓存将副本提供给客户端。这被称为再验证命中或者缓慢命中

缓存一般会使用:(1)if-modify-since;(2)if-match;等HTTP首部进行再验证,会有以下结果:

  1. 再验证命中,服务端响应304
  2. 再验证未命中,服务端响应200并且带有完整内容。
  3. 对象被删除,服务端响应404,缓存清除该资源副本。

1.2 缓存命中率

由缓存提供服务所占的比例被称为缓存命中率,这个数值在0 ~ 1之间,对于现代中等规模以上的WEB应用来说,命中率保持在40%以上就达标了。

1.2 字节命中率

字节命中率直接体现对流量的节省,也能显著的降低时延,但是两者都是评价缓存性能的重要指标。

1.3 区分命中与未命中

检查HTTP报文的Date首部,如果时间早于请求时间,那么就是来自缓存,否则是来自服务端。

二、缓存的拓扑结构

缓存可以是单用户的(私有缓存),也可以是多用户共享的(公共缓存),下面是常见的缓存结构:

client -> private cache -> server
client -> public cache -> server
client -> private cache -> public cache -> server

2.1 私有缓存

Web浏览器中有内建的私有缓存。

2.2 公共代理缓存

公共缓存时特殊的共享代理服务器,被称为缓存代理服务器

2.3 代理缓存的层次结构

在代理缓存层次结构中,在靠近客户端的一级缓存中未命中的请求会被导向更高的父缓存,具体结构如下:

client/(private cache) -> first cache -> parent cache -> server

2.4 网状缓存、内容路由以及对等缓存

有些网络结构会哦固件负载的网状缓存(cache mesh),与缓存之间会以更加复杂的方式对话,可以做出动态缓存通信决策,决定与哪一个父缓存通信,或者直接与源服务器通信,也可将这种结构称为内容路由(content router),它具有以下功能:

  • 根据URLparent cacheserver之间做动态选择。
  • 根绝URL动态选择parent cache
  • 允许该结构其他缓存对缓存的副本进行访问,但是不允许外网流量访问。

三、缓存处理步骤

对一条HTTP GET报文的基本缓存处理步骤为:

  1. 接收。
  2. 解析,提取报文的URL以及headers
  3. 查询,在本地查询是否有已保存副本。
  4. 新鲜度检测。
  5. 创建报文,根据检测结果创建响应报文。
  6. 日志,可选的记录日志。

四、保持副本新鲜

4.1 过期日期和使用期

服务器使用HTTP/1.0+expires或者HTTP/1.1cache-control:max-age=value来规定缓存的使用时间区间。expires是绝对时间,依赖于客户端的始终,而cache-control使用的是相对时间,所以现在更倾向使用后者。

4.2 服务器再验证

如果已缓存的内容到期了(强缓存),那么会重新请求服务器对资源进行验证,如果未修改,返回304,更新缓存副本的首部;如果已修改,则返回200,然后丢弃原来的副本,缓存新的副本。

4.3 条件再验证

如果采取了协商缓存策略,那么可以发起条件GET,只有当条件满足了,服务端才会返回对象。HTTP定义了5个条件首部:

  1. if-modified-since:<date>,如果从指定日期之后文档修改了,则从服务端返回新的对象(响应报文配合last-modified使用)。
  2. if-none-match:<tags>,如果tag与服务端指定资源的标记不同,则条件为true,返回新对象(响应报文配合etag:xxx使用)。
  3. if-unmodified-since:<date>,在进行部分文件传输时,获取其他部分之前要确保文件未发生改变。
  4. if-range,针对不完整文档的缓存。
  5. if-match,与服务器通信时的并发控制。

4.3.1 if-none-match的必要性

  1. 有些文档会被周期性重写,尽管内容没改变,但是时间改变了。
  2. 有些文档的修改不重要,也许只是修改了注释之类的,则不需要重新获取。
  3. 有些服务器无法准确的判定最后修改日期。
  4. if-modified-since的时间粒度是秒,而有些文档可能在1秒内发生数次变化。

4.3.2 使用if-none-match和if-modified-since的时机

HTTP/1.0可能不能理解实体标签,所以服务端返回响应的时候最好同时返回last-modifiedetag这样可以使HTTP/1.0也能正常响应,如果服务端同时返回这两个首部,那么只有当这两个条件都满足,服务端才能返回304

五、如何控制缓存

按照优先级递减的顺序,服务端可以设置以下首部到响应报文中:

  • cache-control:no-store
  • cache-control:no-cache
  • cache-control:must-revalidate
  • cache-control:max-age
  • expires
  • 不设置相关头部,让缓存自己决定过期时间,可能是首部的date减去last-modified的五分之一(知乎上有人称之为启发式缓存)

5.1 缓存首部

  • cache-control: no-store,会阻止缓存对响应进行复制即不缓存。
  • cache-control:no-cache,可以被私有缓存复制保存在本地,但是在提供给客户端使用必须会与服务端进行再验证。
  • cache-control: max-age=100,缓存的活跃时间。
  • cache-control:s-maxage=100,针对公共缓存设置的缓存活跃时间。
  • expires:Fri,05 Jul 2020,05:00:00 GMT,绝对活跃时间,即在指定时间之前是活跃的。
  • cache-control: must-revalidate,如果不添加这个首部,有的缓存为了提高性能会给客户端提供过期的副本,添加这个首部告诉缓存在副本过期后必须重新请求,如果服务端不可用就必须返回504 gateway timeout

5.2 试探性过期

如果响应首部没有设置副本的过期时间,那么缓存会采取一定的算法计算出一个试探性的生存周期,比较常见的是LMF-Factor算法,具体计算公式为:lm_facotr * max(0, date - lastModified),一般lm_factor会取0.2。有的缓存保守起见会直接默认副本活跃时间为0,有的缓存则会设置最大值为1天或者1周。

5.3 客户端的新鲜度限制

当我们点击浏览器的刷新按钮重载页面时,一般来说浏览器会强制刷新缓存,客户端可以在请求首部加入cache-control以加强或者放松对过期时间的限制:

  • max-stale[=<s>],如果只设置了max-stale表明客户端可以接受过期的缓存,如果设置了max-stale=100,就说明该缓存的副本在100s内不会过期,相当于是放松了对缓存过期时间的管控。
  • min-fresh=<s>,要求在指定时间内是有效的。
  • max-age=<s>,生命周期小于设置的值的副本就会被认为过期,相当于缩短了服务端设置的max-age
  • no-cache,强制缓存进行再验证。
  • no-store,强制缓存删除相关文档。
  • only-if-cached,只有当缓存中有该请求的副本,客户端才能获取到该对象(意思是必须从缓存取而不是服务器?)

参考文献

[1]《HTTP权威指南》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容