新鲜度
理论上来讲,当一个资源被缓存存储后,该资源应该可以被永久存储在缓存中。由于缓存只有有限的空间用于存储资源副本,所以缓存会定期地将一些副本删除,这个过程叫做缓存驱逐。另一方面,当服务器上面的资源进行了更新,那么缓存中的对应资源也应该被更新,由于HTTP是C/S模式的协议,服务器更新一个资源时,不可能直接通知客户端更新缓存,所以双方必须为该资源约定一个过期时间,在该过期时间之前,该资源(缓存副本)就是新鲜的,当过了过期时间后,该资源(缓存副本)则变为陈旧的。
驱逐算法用于将陈旧的资源(缓存副本)替换为新鲜的,注意,一个陈旧的资源(缓存副本)是不会直接被清除或忽略的,当客户端发起一个请求时,缓存检索到已有一个对应的陈旧资源(缓存副本),则缓存会先将此请求附加一个If-None-Match头,然后发给目标服务器,以此来检查该资源副本是否是依然还是算新鲜的,若服务器返回了 304 (Not Modified)(该响应不会有带有实体信息),则表示此资源副本是新鲜的,这样一来,可以节省一些带宽。若服务器通过 If-None-Match 或 If-Modified-Since判断后发现已过期,那么会带有该资源的实体内容返回。
下面是上述缓存处理过程的一个图示:
对于含有特定头信息的请求,会去计算缓存寿命。比如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 可以由多个字段组合而成,主要有以下几个取值:
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)
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net