Web缓存分析

前言

不论是在移动端还是前端,web缓存(Http缓存)都是很重要的一部分。在移动端,对于用户流量控制的优化,web缓存就起到了决定性的作用。最开始接触这块是在使用OkHttp的拦截器修改Http请求头进行web缓存,后来仔细研究了一下这块。而Web缓存就是客户端和服务端之间通过一种约束,通过新鲜度校验来给客户端提供缓存资源。

Web缓存的好处

  • 缓存可以减少手机流量的消耗
  • 可以更快的响应用户的操作,提升用户体验度
  • 降低资源服务器的压力,减少并发量

Web缓存的分类

  • 手机文件缓存

    由于移动端不像前端,前端开发中浏览器都默认实现了Web缓存,所以我们可以通过请求头的控制来让浏览器自动为我们进行缓存。但是移动端没有这种默认实现Web缓存的容器,所以需要我们自己手动通过文件缓存网络请求过来的报文。Okhttp或者结合Retrofit(一样)都是可以通过OkhttpClient添加一个构造好的Cache实例,其中Cache实例我们需要指定文件路径和大小。具体可以看我这个代码Demo

  • CDN缓存(内容分发网关缓存)

    实际上是网关缓存的一种,而网关缓存又叫反向代理缓存(提前接受客户端发来的原始请求,然后进行按需请求分配)。CDN缓存一般是由网站管理员自己部署,为了让他们的网站更容易扩展并获得更好的性能。通常情况下,浏览器先向CDN网关发起Web请求,网关服务器后面对应着一台或多台负载均衡源服务器,会根据它们的负载请求,动态将请求转发到合适的源服务器上。从浏览器角度来看,整个CDN就是一个源服务器,从这个层面来说,浏览器和服务器之间的缓存机制,在这种架构下同样适用。

  • 代理服务器缓存

    代理服务器是一种处在客户端和服务端中间的服务器,处在两者之间的网络之中。代理服务器以共享缓存的方式保存着报文副本,可以减少客户端到原始服务器的长距离请求。自然访问同一种报文副本的用户越多,代理服务器的利用率越高,缓存的命中率也越高。

  • 数据库缓存

    这是后台开发的时候,缓存从数据库中查找的数据,减少数据库的并发(比如NoSQL)。

共有缓存和私有缓存

  • 共有缓存(Cache-Control: public):这种缓存常见的就是代理缓存,意思就是一个用户群体都可以访问这个缓存服务器,这个缓存服务器缓存了所有群体的报文缓存
  • 私有缓存(Cache-Control: private):这种缓存常见的就是文件缓存(本地缓存),只允许一个用户个体去访问。

Web缓存的层次结构

一般来说,安卓中的图片多级缓存和这个概念不大相同,这里的多级缓存的意思是在客户端和服务端之间部署多级缓存。常见部署如下:

  • 手机文件缓存(浏览器缓存): 一级缓存
  • 小型的局域网内缓存:二级缓存,小型的,代价小,容量小的缓存代理
  • 大型的广域网内缓存:三级缓存 ,大型的,代价高,容量大的缓存代理

Web缓存的流程

先上张图:

web.png
  1. 在客户端发起一次请求的时候,首先一层一层的缓存会根据算法判断缓存中是否存在文档副本,如果不存在的话就会像资源服务器或者父代理缓存服务器(上一级缓存服务器)继续请求客户端需要的资源。
  2. 如果资源副本存在的话就会根据资源的元数据(记录资源在缓存中保存了多长时间以及它被用了多少次)来计算资源的新鲜度,如果资源新鲜的话就直接返回给客户端。
  3. 如果不新鲜的话,会判断资源在缓存中的副本和在资源服务器里面的文本副本是否一致,如果一致表示资源未发生改变,那么仍然还是由缓存返回。
  4. 如果资源发生改变,那么由资源服务器来返回资源给客户端,并且用这份资源存入缓存中。

大致流程就是这样,请求-检验-在验证,下面对于过程的细节详细说说:

文档过期的判断

缓存数据是否过期是由数据的使用期和过期日期共同决定的。

  • 过期时期(新鲜生存期)

    过期时期可以通过Cache-Control的max-age和max-stale或者Expires来设置。其中,Cache-Control中指定的是相对时间,而Expries指定的是数据过期的绝对时间。但是资源服务器的时间经常会出现与客户端不同步的情况(我就遇到过这种坑。。)所以用相对时间更加合理,并且Cache-Control的优先级要高于Expries。

Cache-Control: max-stale = <s> 在指定的秒数里面缓存可以提供过期了的数据
Cache-Control: max-age = <s> 在指定的秒数里面,缓存里面的数据不会过期
Cache-Control: min-fresh = <s> 至少在未来数秒内数据要保持新鲜
Cache-Control: private or public 私有缓存或者共有缓存
Cache-Control: no-cache 提供数据之前必去要去和资源服务器的数据进行比对判断数据是否更新
Cache-Control: no-store 禁止一切缓存
Cache-Control: must-revalidate 告诉缓存,必须严格遵循服务器的规定,验证之后才能提供过期的数据
Cache-Contero: only-if-cached 只有当缓存中有副本的时候,客户端才能获取一份数据副本

需要注意的是

  1. no-cache 不是不使用缓存而是必须比对了之后才能提供,no-store才是完全禁止缓存
  2. 优先级:no-staore>no-cache>must-revalidate>max-age>Exprise

在移动端的开发中,如何控制我们的数据缓存过期时间需要移动端和后台共同商量之后得出一套方案,比如像数据不停变换更新的并且数据量不大的,应该禁用缓存以保证数据的及时性,像周刊,课表这种长期不变的数据应该添加上合理的缓存时间。

  • 使用时间

    所谓使用时间就是数据从资源服务器发出之后,到被客户端收到,一共经历了多久。但是使用时期并不容易计算。因为服务器,代理,客户端之间时间不同步,网络延时,网络传输耗时等等都会造成使用时期难以计算。

    1.直接通过Date首部进行计算

    ​ 这种计算方式我就被坑过,之前直接设置max-age=3600(一分钟)发现一点缓存效果都没有。我发现响应头的Date首部与现在时间不同,慢了好几天。首先要理解Date首部,Date首部是服务器发出相应的时间,并且是服务器的绝对时间,并且Date首部只能是资源服务器设置,代理和缓存都不能修改,时间的描述格式由RFC822定义,所以如果时间不同步的话,直接用客户端时间减去Date来计算使用期是行不通的。

    2.通过Age首部进行计算

    Age首部只适用于HTTP/1.1的设备,Age表示数据从产生到现在经过了多长时间,是个相对时间

    通过Age首部,我们可以累加资源在各个代理中存在的时间,加上数据从资源服务器到缓存的网络传输时间(一般用缓存到服务器,服务器到缓存双向的传输时间来保守估计)。

    所以我们可以看出,完整的使用时期计算应该是如下图:

web2.png

可以看出其实是忽略了客户端到缓存的网络传输时间,多算了缓存到资源服务器的网络传输时间。

再验证

如果第一次缓存未命中的话,就会进行服务器再验证。用来判断服务器的资源是否发生改变。

If-Modified-Since与Last-Modified(基于Date的再验证)

If-Modified-Since是请求字段,值为一个绝对时间,用于通知服务器在这个时间之前,默认资源是未被修改的(不去进行再验证),如果超过了这个时间,就会将这个时间和资源最后修改的时间进行对比,如果小于资源最后修改的时间,那么Last-Modified响应首部会返回资源最后被修改的时间,并且返回200.如果大于最后修改的时间,那么Last-Modified响应首部会返回304表示资源未被修改。

If-None-Match和ETag(基于实体标签的再验证)

ETag可以看作是资源的版本号,并且在强验证器下,资源发生细微的变化都会导致ETag的变化,在弱验证器下,资源发生细微的变化都不会导致ETag的变化,这个“细微”度量标准是由后台开发人员来确定的。客户端可以根据If-Modified-Since来添加你现在所拥有的ETag版本号,发送给服务器,然后服务器进行比较。如果版本号不同,那么就会返回200,并且将最新的ETag值添加到ETag响应头里面。如果相同,返回304。
两者之间并没有优先级之分,如果同时存在,那么客户端和服务端应该将两者综合起来考量。

未经博主同意,不得转载该篇文章

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

推荐阅读更多精彩内容

  • 本篇文章篇幅比较长,先来个思维导图预览一下。 一、概述 1.计算机网络体系结构分层 2.TCP/IP 通信传输流 ...
    涤生_Woo阅读 54,938评论 24 557
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • 本文是《图解HTTP》读书笔记的第二篇,主要包括此书的第六章内容,因为第六章的内容较多,而且比较重要,所以单独写为...
    lijiankun24阅读 1,356评论 0 6
  • 1. 网络基础TCP/IP HTTP基于TCP/IP协议族,HTTP属于它内部的一个子集。 把互联网相关联的协议集...
    yozosann阅读 3,436评论 0 20
  • 在知识变现如此多元化的今天,掌握学习方法,能让你在人群中快速脱颖而出。身为普通人的我们,学习就成了一门非常重要的技...
    陶壹阅读 126评论 0 0