HTTP中缓存的使用期计算(Age Calculation)

来源:互联网 发布:康福软件下载 编辑:程序博客网 时间:2024/06/06 14:14

最近在学习HTTP协议中的缓存机制,看到使用期计算时,真的是被《HTTP权威指南》给绕晕了,之后查看了RFC文档中的Age Calculation部分和其他一些资料,整理如下。


一. Age首部字段介绍

当一份Response Message(响应报文)从缓存里获取的时候,HTTP/1.1协议要求在Resposne Message里添加一个Age header filed(Age首部字段)。这个字段的值表示的是,从这个响应报文在源服务器中产生或者过期验证的那一刻起,到现在为止所经过时间的一个估计值(从名字上其实就看的出来,它表示的是缓存的年龄)。经常和max-age一起来验证缓存是否过期,即如果这个字段的值比max-age的值还大,那这份缓存就已经过期了。

Age值从本质上来说,就是从源服务器到接受端的一路上,响应内容在中间各个节点的缓存中呆的时间,加上响应内容在各个相邻节点间传输所用掉的时间。但HTTP协议不会直接利用这一点来计算Age值,因为直接计算的话,就需要在最终的响应报文上加上响应内容在各个中间节点中停留的时间,并且还需要得到各个相邻节点间的传输时间,非常麻烦。

RFC文档中将当前缓存的Age值的计算转化为了计算收到响应时的Age值,而当前缓存的Age值就等于收到响应时的Age值加上这份响应在本地缓存中停留的时间。


二. 计算收到响应时的Age值

RFC文档里提供了两种计算收到响应时Age值的方法。

用Date字段计算Age

在响应报文的首部中还会有一个Date字段,它的值表示报文内容在源服务器中诞生的时间。于是,接收端可以用收到响应的时间减去Date字段的值就得到Age值。用response_time表示收到响应的时间,用date_value表示Date字段的值,那么

age_value = response_time - date_value

这种计算方式虽然简单,但是有个问题,接收端和源服务器间很可能会有clock skew(时钟偏差),即两台计算机的时钟设置不同。这是非常常见的,所以使用这种计算方式时,推荐使用NTP等时间同步协议来同步接收端和源服务器端的时间。另外,当时间不同步时,Age的计算结果甚至可能是负的,为了减少这种误差,当计算值为负数时,将它置为0,于是这种方法计算Age的公式如下。

age_value = max(0, response_time - date_value)

逐跳计算Age

响应报文的Age还可能以如下思路计算,接收端收到响应报文时的Age值等于上一跳节点中缓存的Age值加上传输时延。用previous_hop_age_value表示上一跳节点中缓存对的Age值,用response_delay表示传输时延,那么计算公式如下。

age_value = previous_hop_age_value + response_delay

respose_delay可以粗略地计算为得到响应时间减去发出请求的时间,这里你可能会问,为什么不要再除以二呢,因为HTTP对Age的计算策略是宁可多算也不肯少算的,多算顶多缓存新鲜时间变短,产生额外的新鲜度验证,但是少算的话,即使过期了,客户端还会把它当成新鲜的用。用request_time表示发出请求的时间,用response_time表示得到响应的时间,那么计算公式如下。

response_delay = response_time - request_timeage_value = previous_hop_age_value + response_delay

这种方法的好处是并不需要端到端的时间同步机制,response_timerequest_time都是本地的时间,不存在时间偏差。但是,其实Age字段是HTTP/1.1中才出现的,在HTTP/1.0中并没有这个字段,所以有可能一些中间节点是计算不了age_value的,从而导致age_value整体偏小。

综合两种方法

综上所述,通常响应报文的计算会综合上述两种方法,取最大的一个。即

age_value_by_date = max(0, response_time - date_value)response_delay = response_time - request_timeage_value_by_hop = previous_hop_age_value + response_delayage_value = max(age_value_by_date, age_value_by_hop)

三. 计算当前缓存的Age

以上说的是如何计算响应到达时的Age。对于本地的一份缓存来说,它当前的Age等于响应到达时的Age值加上这份相应在本地缓存中待的时间。以age_when_document_arrived_at_our_cache表示响应到达时的Age值,以how_long_copy_has_been_in_our_cache表示响应在本地待的时间,那么计算公式如下。

curret_age_value = age_when_document_arrived_at_our_cache + how_long_copy_has_been_in_our_cache
原创粉丝点击