4.2.3. Calculating Age

1 阅读3分钟

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个值都有可能出现偏差:

  1. 偏大;例如服务器时间精准但是本地时间快了。
  2. 偏小(并且response_time > date_value);例如服务器时间精准但是本地时间慢了一点点。
  3. 偏小(并且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;