4.2.3. Calculating Age
rfc 7234 4.2.3. Calculating Age
apparent_age
rfc定义的一种age计算方式得出的结果,这是一个公式值,并不是理论值。对应收到response那一刻的age。
误差导致的结果
如果本地时间和服务器时间有很好的同步,那么根据age的定义,可以通过如下方式计算age值
response_time - date_value
由于这2个值都有可能出现偏差:
- 偏大;例如服务器时间精准但是本地时间快了。
- 偏小(并且response_time > date_value);例如服务器时间精准但是本地时间慢了一点点。
- 偏小(并且response_time < date_value);例如本地时间慢的离谱。
对于1.结果,虽然它更早的过期了,但是在使用时它是有效的; 对于2./3.结果,这会导致过期版本被错误使用。
rfc又做如下定义:
apparent_age = max(0, response_time - date_value);
误差的来源
以下为举例,并不包含每个值的所有情况。
response_time:
- 本地时间偏快
- 本地时间偏慢
date_value:
- 服务器时间偏快
- 服务器时间偏慢
- 链路中的intermediate修改Date
当没有date_value时如何处理?
Okhttp直接使用收到请求的时间(response_time),这导致apparent_age的计算结果为0。
corrected_initial_age = max(apparent_age, corrected_age_value);
在这种情况下,根据公式,corrected_initial_age的值由corrected_age_value决定。
corrected_age_value
rfc定义的一种age计算方式得出的结果,这是一个公式值,并不是理论值。对应收到response那一刻的age。
请求流程图:
origin server cache
|-------------age_value----------->|
|---request interval-->|-----response interval--->|
client client
根据age的定义结合上述流程图可以得出如下公式:
理论age = age_value + response interval
同时我们将rfc中给的公式进行等价变形:
corrected_age_value = age_value + response_delay;
由于:
response_dely = request_interval + response_interval
所以:
corrected_age_value = age_value + request_interval + response_interval
理论age vs corrected_age_value
根据前面的推论可以看出corrected_age_value比理论值多了request_interval。
为什么rfc接受多出来的request_interval?
目前已知的原因就是:
没法精确计算request_interval,但是可以通过“response_time - request_time”来相对精确的计算“request_interval + response_interval”。虽然最终的age计算偏大,但是能保证response的fresh的判定结果始终是有效的。
误差问题
corrected_age_value = age_value + response_delay;
根据公式,虽然response_delay是用本地时间计算出来的差值相对精确,但是age_value是response的sender计算的,不受我们控制;所以corrected_age_value的结果也可能会出现偏大/偏小的情况。
corrected_initial_age
corrected_initial_age是一个校准后的值,它对应收到response时的age。
公式理解
corrected_initial_age = max(apparent_age, corrected_age_value);
既然apparent_age和corrected_age_value都有可能不准,不如就取个最大值好了。
current_age
current_age对应当前时刻的age;这是一个公式值并不是理论值。
公式理解
response_time now
----age when received ----|----resident_time----|
client client
结合上图,不难理解rfc中定义的公式:
resident_time = now - response_time;
current_age = corrected_initial_age + resident_time;
理解开头这段话
The Age header field is used to convey an estimated age of the
response message when obtained from a cache. The Age field value is
the cache's estimate of the number of seconds since the response was
generated or validated by the origin server.
为什么说“estimated”?:
rfc使用了公式来计算age值,这个值不一定准确(有可能阴差阳错刚好等于理论上的age)。
“generated or validated”:
generated时:
response_delay = request_generated.response_time - request_generated.request_time;
validated时:
response_delay = request_validated.response_time - request_validated.request_time;