1. 测试环境
注意事项:
(1)服务器端得添加防火墙规则或者直接关闭,测试的话建议直接关闭!
(2)保持源站,缓存服务器,客户端的时间同步,这个对后续测试缓存超时lm-factor算法精确度上有影响。
2 实测项目
2.1 请测试不匹配refresh_pattern或者hash_refresh_pattern任何规则的URI从返回后cache缓存的情况?
这里缓存服务器端采用默认squid.conf, 不添加refresh_pattern, hash_refresh_pattern 规则验证
2.2.1 源站没有指定Expires ,Cache-control等头信息
测试客户端第一次请求,缓存服务器(后续简称CDN)是miss的,这时候会回源去取文件,再返回给客户端,之后将文件缓存下来。这时候其实有个默认的max-age产生,过期时间为259200秒。后续在这个缓存时间内,客户端的请求,CDN都会直接返回缓存文件,产生一次hit命中。超过这个缓存时间的请求,CDN会回源确认缓存文件是否有修改,有修改则先更新文件再返回客户端,没修改则直接本地缓存文件返回给客户端。
客户端一次请求,CDN miss,回源取文件返回给客户端
CDN 上面抓到往host:www.pylt.com 的GET请求
注: 这里的max-age=259200
客户端的第二次请求,CDN直接是hit命中返回
2.1.2 源站指定no-cache
对于源站指定no-cache,no-store等头信息时,CDN默认是不缓存,所以客户端的每次请求,CDN都会miss, 然后回源取文件返回客户端。
第一次请求miss
第二次请求也是miss
CDN 对客户端每次请求都抓到回源GET信息
2.1.3 源站指定max-age
对于源站指定max-age信息,CDN这边会默认采用给定的max-age作为文件缓存时间,超过这个时间后,客户端如果有请求,CDN会发送带有If-Modified-Since头信息的请求回源确认文件是否修改,有修改则先更新文件再返回客户端,没修改则直接本地缓存文件返回给客户端,并产生一次hit命中。下面例子中,源站设置的max-age为60s
客户端第一次请求 miss
max-age 时间内,请求都是hit
缓存时间操作max-age时,CDN回源确认文件是否有修改过
总结: 对于no-store , Expires < now 等其他情况,CDN默认不配置refresh_pattern 或 hash_refresh_pattern 情况下,都会遵从源站的方式,如no-store ,则不会在本地保存文件,客户端来的请求,CDN回源 ,Expires < now 则对于客户端来的请求,CDN 每次都会回源验证文件是否修改。
2.2 验证LM-factor算法
Squid 完整的缓存机制:
FRESH if expires < now, else STALE
STALE if age > max
FRESH if lm-factor < percent, else STALE
FRESH if age < min
else STALE
从上往下,也代表着缓存控制策略的优先级由高到底!!
这里我打算按照squid 完整缓存机制验证下不同条件下,对于缓存过期时间的判断,同时也包含lm-factor
2.2.1 FRESH if Expires < now
客户端第一次请求
客户端第二次请求
可以看到服务器端expires 配置过期时间为2012年XX ,而当前时间响应时间为2014年XX ,满足Expirs < now 。默认不忽略Expires情况下,第一次请求CDN miss ,后续每次请求, 缓存文件都是过期的,cache机器都带着‘If-Modified-Since’ 回源验证,如下图:
2.2.2 STALE if age > max
Squid.conf max: 3min(180s)
先简单介绍下refresh_pattern, 即为squid缓存控制规则
-i : 该规则对大小写敏感,-i 可以忽略大小写
\.html$ : url正则匹配,测试环境我请求的是html文件,可以简单这么写
1: min 文件在机器上的最小缓存时间(分钟),age<min 则代表fresh ,不过优先级在lm-factor 之后
5: max 文件在机器上的最大缓存时间(分钟),age>min 则代表stale ,文件过期
refresh_pattern 还有一些额外的options参数,下面会有详细补充验证。
虽然age > max 文件一定过期,但可能在max之前根据算法文件就提前过期了。为了验证max,此时的resource_age 已经足够大,lm-factor percent < 50% , 忽略掉lm-factor影响,lm-factor后续再解释,这里只有当age > max 时缓存才会过期。
Age 代表缓存文件从第一次进入cache后到当前时间经历多长时间,每次缓存过期回源验证之后,age 进入cache的时间需要更新到当前时间。这里简单理解Age 就是缓存时间。
这里我从客户端每秒访问一次文件,并获取返回的Age值,测试发现每3分钟后,Age重新刷。而cache服务器上也可以在这时刻抓到回源验证的request
上面可以看到Age > 180s后,缓存过期,对于下一次的请求CDN回源验证文件
2.2.3 LM-factor < percent
Date : 对象进入缓存的时间
resource_age = Date - Last-Modified
response_age(Age) = now - Date
LM-factor=(response_age)/(resource_age)
Fresh If LM-factor < percent
这里的percent 设置的是 50% ,所以根据算法 如果lm-factor < 50% ,则缓存文件未过期,否则为过期,再次请求,CDN需要回源验证。
验证实例,在客户端每秒请求1次文件,记录下Age.(即response_age) , 每一次刷新时,记录下文件Last-Modified头,用于做对比。
计算下:
resource_age = 17:01:55 - 17:01:09 = 46S
reponse_age = cache_time renew = Age + 1 = 23S
LM-factor = 23S/46S = 50%
当LM-factor = 50%时,缓存过期了,即Fresh:If LM-factor < percent成立
下面还有另外一例子,计算方法一样,需要注意的时,回源验证之后,resource_age = now - Last-Modified
可以看到,当LM-factor < percent 时,缓存文件是fresh , 否则为stale
2.2.4 FRESH if age < min
因为age < min的判断条件在,Expires ,lm-factor等之后,所以实验环境先满足这些判断未过期,再来验证age < min 情况
Age < min的详细测试可以看加上override-lastmod参数之后,这里
测试比较简单如下:
2.3. 配置验证 refresh_pattern [-i] regex min percent max [options] 的URI从源返回cache缓存的情况:
# override-expire
# override-lastmod
# reload-into-ims
# ignore-reload
# ignore-no-cache
2.3.1 override-expire
该选项导致 squid 在检查 Expires 之前,先检查 min 值。这样,一个非零的 min 时间让 squid 返回一个未确认的 cache 命中,即使该响应准备过期。
源站 Expires 配置
CDN refersh_pattern 配置
客户端第一次请求回源
可以看到override-expire忽略掉源站的过期时间,未忽略情况,上文测试提到过,客户端的每次请求,cache机器都要回源验证确认文件的Last-Modified。
2.3.2 override-lastmod
该选项导致 squid 在检查 LM-factor 百分比之前先检查min ,它生效在expire 之后。相当于min的优先级比LM-factor高了。
源站默认不设置
CDN 设置了override-lastmod ,min = 60s
前面验证过了lm-factor percent 算法,如果此时遵循lm 算法的话,Age 应该在等于5s 的时候,缓存就过期,cache机器回源重新验证。可事实不是如此,那么lm-factor percent 何时才生效?
可以看到,在1分钟的时候,缓存过期了,cache机器回源验证
说明override-lastmod 使得 min的优先级高于lm-factor ,在age < min 时即使response_age/resource_age > lm-factor percent , 缓存也不会过期,等age > min 时,这时候lm-factor就会生效。
2.3.3 reload-into-ims
该选项让 squid 在确认请求里,以 no-cache 指令传送一个请求,但squid 在转发请求之前,对该请求增加一个 If-Modified- Since 头部。注意这点仅仅在目标有 Last-Modified 时间戳时才能工作。外面进来的请求保留 no-cache 指令,以便它到达原始服务器。
客户端提交含有no-cache的请求
默认情况下,客户端提交no-cache请求到CDN,CDN取完文件后并不缓存的。 这里refresh_pattern 加上 reload-into-ims 之后会CDN会强行缓存文件,并且对于客户端每次过来带有no-cache的请求都回源确认。
CDN机器上抓到对于客户端no-cache的请求,CDN都带上If-Modified-Since回源确认
2.3.4 ignore-reload
该选项导致 squid 忽略请求里的任何 no-cache 指令。
默认不加ignore_reload 情况下
对于客户端的no-cache请求,不加ignore-reload情况,cache机器不缓存文件,每次都回源GET
下面开启ignore-reload 看下效果:
说明ignore-reload确实生效了,cache机器忽略掉客户端过来的请求中的no-cache
2.3.5 ignore-no-cache 忽略源站的no-cache
源站no-cache设置
CDN 设置
可以看到,CDN把源站的no-cache给忽略,客户端请求直接hit命中