HTTP 缓存新鲜度 max-age

新鲜度


理论上来讲,当一个资源被缓存存储后,该资源应该可以被永久存储在缓存中。由于缓存只有有限的空间用于存储资源副本,所以缓存会定期地将一些副本删除,这个过程叫做缓存驱逐。另一方面,当服务器上面的资源进行了更新,那么缓存中的对应资源也应该被更新,由于HTTP是C/S模式的协议,服务器更新一个资源时,不可能直接通知客户端更新缓存,所以双方必须为该资源约定一个过期时间,在该过期时间之前,该资源(缓存副本)就是新鲜的,当过了过期时间后,该资源(缓存副本)则变为陈旧的。

驱逐算法用于将陈旧的资源(缓存副本)替换为新鲜的,注意,一个陈旧的资源(缓存副本)是不会直接被清除或忽略的,当客户端发起一个请求时,缓存检索到已有一个对应的陈旧资源(缓存副本),则缓存会先将此请求附加一个If-None-Match头,然后发给目标服务器,以此来检查该资源副本是否是依然还是算新鲜的,若服务器返回了 304 (Not Modified)(该响应不会有带有实体信息),则表示此资源副本是新鲜的,这样一来,可以节省一些带宽。若服务器通过 If-None-Match 或 If-Modified-Since判断后发现已过期,那么会带有该资源的实体内容返回。

下面是上述缓存处理过程的一个图示:

Show how a proxy cache acts when a doc is not cache, in the cache and fresh, in the cache and stale.

对于含有特定头信息的请求,会去计算缓存寿命。比如Cache-control: max-age=N的头,相应的缓存的寿命就是N。

通常情况下,对于不含这个属性的请求则会去查看是否包含Expires属性,通过比较Expires的值和头里面Date属性的值来判断是否缓存还有效。如果max-age和expires属性都没有,找找头里的Last-Modified信息。如果有,缓存的寿命就等于头里面Date的值减去Last-Modified的值除以10(注:根据rfc2626其实也就是乘以10%)。

缓存失效时间计算公式如下:

expirationTime = responseTime + freshnessLifetime - currentAge

上式中,responseTime 表示浏览器接收到此响应的那个时间点。

Cache-Control


Cache-Control 可以由多个字段组合而成,主要有以下几个取值:

扫描二维码关注公众号,回复: 14961454 查看本文章

1. max-age 指定一个时间长度,在这个时间段内缓存是有效的,单位是s。例如设置 Cache-Control:max-age=31536000,也就是说缓存有效期为(31536000 / 24 / 60 * 60)天,第一次访问这个资源的时候,服务器端也返回了 Expires 字段,并且过期时间是一年后。

在没有禁用缓存并且没有超过有效时间的情况下,再次访问这个资源就命中了缓存,不会向服务器请求资源而是直接从浏览器缓存中取。

判断缓存是否过期


response_is_fresh = ( freshness_lifetime > current_age )
    • freshness_lifetime:按优先级,取以下响应头部的值
             • s-maxage > max-age > Expires > 预估过期时间
                  • 例如:
                               • Cache-Control: s-maxage=3600(1小时)
                               • Cache-Control: max-age=86400(1天)
                               • Expires: Fri, 03 May 2019 03:15:20 GMT
                                     • Expires = HTTP-date,指明缓存的绝对过期时间

为什么要预估缓存时间?


55%的请求没有携带max-age,也就是没有告诉客户端这个资源要不要缓存。

有些内容是不怎么相对变化的,比如图片,比如js css这些,但是服务器配置这些有问题,没有考虑到带宽的优化,体验性的提升,所以没有配置描述缓存过期时间的内容。

浏览器有默认缓存时间。

常见的预估时间


• RFC7234 推荐:(DownloadTime– LastModified)*10%

浏览器获取到响应的时间,lastmodify就是服务器端显示的就是上次资源修改的时间。这两个时间相减*10%。

浏览器端缓存无请求


expire 在浏览器端验证expire是否大于当前时间,若大于则不发送http请求,直接cache返回,F5强刷会绕过

Expires: Sun, 10 Feb 2002 16:00:00 GMT

max-age 与expire功能类似,记录的是一个时间长度(秒)。Expires在HTTP/1.0生效,Cache-Control:max-age在HTTP/1.1生效。max-age支持的情况下,优先级高于expire,expire值不生效。

Cache-control: max-age=5

Age 头部及 current_age 的计算


• Age 表示自源服务器发出响应(或者验证过期缓存,最初生成响应的时间),到使用缓存的响应发出时经过的秒数

       • 对于代理服务器管理的共享缓存,客户端可以根据 Age 头部判断缓存时间
       • Age = delta-seconds
current_age 计算: current_age = corrected_initial_age + resident_time
           • resident_time = now - response_time(接收到响应的时间)
             • corrected_initial_age = max( apparent_age , corrected_age_value )
                 • corrected_age_value = age_value + response_delay
                       • response_delay = response_time - request_time(发起请求的时间)
                 • apparent_age = max(0, response_time - date_value)

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/130494085