squid;Date与Expires;refresh_pattern
http://www.361way.com/squid-date-expires/2239.html
squid中的时间和过期
引言:
Squid作为一个缓存工具,其核心的功能就是缓存。那么判断一个obj是否缓存以及缓存多久就是极为重要的工作。事实上目前我们SQUID开发的很多内容都是和这个问题有关。Squid在过期时间处理上有其独有的细致一面:不可避免的就会引入复杂的一面。理解squid就必须理解过期时间处理。这也是用好squid的一个前提。
1. squid过期相关的基础知识
1.1 概述
谈论squid就不得不谈论HTTP,谈论HTTP则必须提及RFC2616.
RFC2616文档(http1.1协议)定义了一系列的规则,我们需要就这些规则来指导我们的行为(也许跟据需求做相反的事情)。
HTTP缓存被定义为:除去许多情况下的对发送请求的需求,和除去在其他许多情况下发送完整响应的需求。前者需要控制不必要的网络奔波去下载不需要的东西,而后者是控制对不需要的东西仅请求不下载。这就牵扯到过期机制的两个组成方式:截止机制和验证机制。
截止机制:通俗说就是过期时间。HTTP缓存效率最大值的表现。如果一个资源(URI)仅仅从本地缓存目录中提取而产生响应无疑是最省力的。换句话说,缓存能够不必首先联系服务器而返回响应。
验证机制:和截止机制相关的。即在截止机制中设置了一个过期时间。当超过这个时间时,会收到一个带有验证请求的访问发往缓存而不是一个正常请求。如果缓存中的副本未有变化,则采用304Not Modified来说明此问题。否则必须回复完整响应(包含实体body)。
1.2 Date与 Expires
Date和Expires都是表示绝对时间的概念,其不同点在于:
Date给出的是响应发出的绝对时间。
格式为:
“Date:” HTTP-date |
Expires给出响应的内容过期的绝对时间。
格式为:
“Expires:” HTTP-date |
例如,今天是3月25日,apache源站设置了
ExpiresActive on
ExpiresDefault “access plus 1 month” |
那么请求该源站返回的header中就应该包括
Expires: Fri, 24 Apr 2009 08:00:57 GMT |
注意:
a. Date与Expires都是绝对时间。
b. Date与Expires通常是格林尼治标准时间(如果后面带有GMT),也就是比北京时间早8个小时。
1.3 Age与max-age
这两个概念是比较容易搞混的。其相同点是:
a. 都是响应头的一部分
b. 都是一个时间长度,以秒为单位
但主要是不同点:
其中age是指:自从这个响应在源站服务器上生成以来(而不是源站内容修改以来!!),到现在所经历的秒数。
Age通常只对cache才有意义。
其格式为:
“Age:”age-value |
max-age是指:一个响应被源站发出后,在cache当中存活的时间,换句话说,一个响应的Age值如果超过了max-age,就认为这个响应是过期的。
当然,max-age也是对于cache才有意义。
其格式为:
“Cache-control: max-age=” max-age-value |
再次重申:max-age比Expires更加优先!
1.4 If-Modified-Since与Last-Modified
如果一个内容真的过期了,怎么办?从源站重新下载吗?
当然不。http协议对于过期的内容的处理,是先到源站验证一下,这个内容有没有发生改变,如果没有改变过,当然就不用重新下载了。这种验证是通过 If-Modified-Since等一系列http头实现的。
If-Modified-Since是http请求头的一部分,它表示客户端向源站询问“这个内容自从x年x月x日x时起,是否变过?”
其格式为:
“If-Modified-Since:” HTTP-date |
如果源站发现该内容变过,则会返回一个200OK的响应,并把新的内容发回来给客户端。
如果源站发现内容没有变过,则会返回一个304的响应,告诉客户端“没有改变过,你的内容还是可以用的”,这种情况下就不用发送内容了,可以大大节省传输带宽。
注意:
a)如果客户端发的If-Modified-Since后面的日期是非法的日期,源站将直接返回200OK+新内容。
b) If-Modified-Since后面跟的日期是客户端上一次接到的响应中,Last-Modified的值。
Last-Modified是响应头的一部分,是源站给出的,一个内容在源站上最终更新的时间。
对于静态内容,Last-Modified是文件的更新时间,对于动态内容,取决于源站的具体实现。
其格式为:
“Last-Modified:” HTTP-date |
1.5 Etag与If-None-Match
有的时候,Last-Modified 与 If-Modified-Since不能够可靠地标示内容的改变,这就需要Etag等更加可靠的打标签的机制。
Etag是响应头的一部分,是源站对内容所打的一个标签,用来标示这个文件,这个标签当且仅当内容变化才会变化,就像md5码一样。
与md5码不同的是,打Etag不需要读取整个文件的内容,比md5消耗的资源要少得多。
Etag起到的作用跟Last-Modified差不多,都是标示内容的变化,只是比Last-Modified更可靠。
If-None-Match是请求头的一部分,它表示客户端向源站询问“这个内容的标签还是不是xxxxxx?”
如果源站发现该内容变过,则会返回一个200OK的响应,并把新的内容发回来给客户端。
如果源站发现内容没有变过,则会返回一个304的响应,告诉客户端“没有改变过,你的内容还是可以用的”,这种情况下就不用发送内容了,可以大大节省传输带宽。
2. 目前过期时间部分我们的squid是如何实现(修改)的
2.1 squid碰到了什么困境
如上的squid描述我们可以看出squid在处理过期时间方面的支持是很强大也很全面的。但我们仍然发现一些因源站给出错误header导致我们缓存过期的问题(通常出现此问题即出现连续过期)。很多客户囿于技术/策略问题,将控制权交给我们。此时,我们就需要squid理顺过期关系进行自维护的处理。
2.2 mod_use_server_date做了什么
mod_use_server_date做的最重要的一件事情,就是确定一个obj的“起始”时间。知道一个obj从什么时候“出生”,然后知道其生存时间,即可完全决定其在squid的生存时间。第二件重要的事情就是“推定”经过其他squid设备的obj的“起始”时间。下面画图说明此问题:
如上图所示,在菱形时间点发生了请求,下层去获取OBJ进入squid群组和过期时间。
从上图我们可以发现其中核心功能实现是max-age(或者由expire和date计算得到)。而多层squid之间的交流主要靠AGE。也就是说:
Max-age(或者由expires-date计算得到)决定OBJ生存时长
Age决定OBJ的出生时间点 |
2.3 expires和refresh_pattern哪个在生效
如上(2.2节)是use_server_date的设计大意。那么在复杂的网络条件下,如何知道“是expires功能生效呢,还是refresh_pattern策略生效呢?”
要回答这个问题,首先要确认的是:
配置的refresh_pattern, URL对应行是否配置override-expire:
1)如果配置了,refresh_pattern生效,忽略过期时间 2)如果没有,先检查过期时间,再检查refresh_pattern |
目前我们的默认配置都是
ignore-reload 和override-lastmod(稍后讲解refresh_pattern时解释)所以可以不用注意如上问题。
如果确认如上refresh_pattern没有配置override-expire,则遵循如下规则:
如果源站给的信息可以计算出OBJ生存时间,则OBJ不走refresh_pattern
源站给的header可能: 1)有max_age 2)有expires和date 3)仅有expires 上述3者关系是顺序优先匹配,如果1符合就不需要2、3,同理2符合就不需要3. 满足此3项的为可计算生存时间的OBJ. |
有如上3个条件符合所得出的过期时间也不尽相同。
squid的处理策略,
如果源站给的Header符合:
1)有max_age
2)有expires和date
则结果相同,过期时间是squid最初服务时间+max-age或者是squid最初服务时间+源站expire-源站date。
如果源站给的Header符合:
3)仅有expires
则以此header数据为准,绝对时间设置过期。
3. 目前的refresh_pattern使用情况和存在问题
3.1 refresh_pattern概述
refresh_pattern是squid.conf中关于过期的一种配置项。
通常如下格式:
refresh_pattern -i ^http 1440 0% 1440 ignore-reload override-lastmod |
我们可以分解一行配置行为:
l 功能节名:refresh_pattern
l URL正则匹配区:-i ^http (-I含义为是否区分大小写)
l Age&lm-factore区:1440 0% 1440
l Options区:ignore-reload override-lastmod等
前二区目前没有疑问,下面就后二区详细介绍。
3.2 Age&lm-factore区
本区有3个配置节 分别为 min percentage max。
Min:是指一个object在缺少明确的Expires的情况下,能够确定的在cache中被认为新鲜的分钟数(小于此值肯定是新鲜的)。这个参数推荐设为0,否则会造成动态应用中的内容被不正确地缓存住。
Max:是指一个object在缺少明确的Expires的情况下,在 cache中可能被认为新鲜的分钟数的最大值(大于此值肯定是过期的)。
percentage是指,一个object在缺少明确的Expires的情况下,它的LM-factor的最大值(LM-factor超过此值则认为过期,否则新鲜)
LM-factor= (当前时间-到达cache的时间) / (到达cache的时间 – Last-Modified) * 100% |
关于LM-factor,在《Squid: The Definitive Guide》一书中,有一个更加形象的图来说明这个概念。
LM-factor是HTTP协议中关于Last-Modifed时间参与过期计算的一个模糊处理过期时间的方式(如果不指明某URL过期时间)。显然在我们目前的应用下,是不该使用此项模糊策略的。我们目前线上机器配置percentage为0%,已经省略此功能节。
3.2 Options区
我们squid使用squid2.7,其options区目前可以有:
- override-expire: 强制min在expires前生效。
- override-lastmod: 强制min在lm-factor之前生效(在expire之后)。
- reload-into-ims:将no-cache或者reload请求转化为IMS请求给源站。
- ignore-reload:将no-cache或者reload请求头忽略。
- ignore-no-cache:强制忽略从源站而来的“Pragma: no-cache”和“Cache-control: no-cache”
- ignore-private:强制忽略从源站而来的“Cache-control: private”
- ignore-auth:强制将一个请求认为是源站发送的带有“Cache-control: public”
- stale-while-revalidate=NN:强制在过期时间生效后的NN秒内非过期
- ignore-stale-while-revalidate:强制忽略源站带有的“Cache-Control: stale-while-revalidate=NN”header
- max-stale=NN:强制将一个超过NN秒的OBJ设置为未缓存,即使其在cache,或者更新失败。
- negative-ttl=NN:强制此行refresh_pattern的negative_ttl时间,即使全局已经有过期时间设置。
3. SQUID 304的修改
Squid如果缓存了一个OBJ,且其未过期时,如果碰到客户端来请求更新此obj,则squid向下发送的304/Not Modified中的header不能进行更新(特别是Date和Expires),还是给源站给的。此时会导致客户的IE中的date和expires 显示为很早之前的(上层一直缓存的)。 在这种情况下源站不发送过期时间靠我们refresh_pattern进行判断的话,则不能刷新客户端的缓存记录时间。
此问题虽然可以使用update_headers来规避,但是显然其开销是非常大的。SQUID 304修改可以在无损状态下修复此问题。对于关闭update_headers导致304较多或者源站未给明确过期时间的请求,修改后都可以看到很明显
以上内容摘自于互联网。
http://www.aminglinux.com/bbs/thread-916-1-1.html
这个东西是用来设置对象缓存时间的。
首先理解 refresh_pattern 语法: refresh_pattern [-i] regexp min percent max [options]
例如:
refresh_pattern \.(jpg|png|gif|mp3|xml|css|js)$ 1440 50% 28800 ignore-reload
-i 其实就是是否区分大小写,加上这个参数就是不区分。 regexp代表正则表达式,上例中表示以jpg|png|gif|mp3|xml|css|js 结尾的这些文件,当然这里的| 表示 或 的意思。
几个概念:
resource age =对象进入cache的时间-对象的last_modified,简单点理解就是从对象被缓存到对象被修改之间的时间
response age =当前时间-对象进入cache的时间,简单理解就是对象已经被缓存了多久
min和max为时间,单位是分钟,上例中 1440就是1天,28800就是20天。
百分比,这个东西用来衡量一个文件的存活时间。存活时间= resource age * 百分比。
[options]
如果希望页面一进入cache就不删除,直到被主动purge掉为止,可以加上ignore-reload选项. 一般情况可以使用 reload-into-ims
最后说说,如何判断一个文件是否过期:
1. 首先计算出response age
2. 当response age <= max时,对象不过期,而>max时就过期了
3. 当response age介于两者之间时,就需要看 存活期了,当存活期 > response age 时则过期,否则不过期。
过期了的话,squid并不会删除对象,当有请求来访问该文件时,则squid会到前端的web上去读取新的文件,但是squid还是会把当前的文件和web上的文件做对比,如果改了则重新拉取过来缓存,否则不拉取,直接更改resource age 。
http://www.80aj.com/2339.html
121017 squid.conf 中 refresh_pattern 参数说明[转载]
refresh_pattern : 只对原始内容【即原始服务器】头部没有设置Expires过期时间的页面起作用,比如论坛页面;而对类似apache mod_expires 设置过的页面不起作用。
说明之前,先将个概念LM,LM就是页面Header里时间(Date)和Last-Modified时间的差。Date一般是Squid从后面取页面的时间,Last-Modified 一般是页面生成时间。
用于确定一个页面进入cache后,它在cache中停留的时间.refresh_pattern 规则仅仅应用到没有明确过时期限的响应.原始服务器能使 用 Expires 头部,或者 Cache-Control:max-age 指令来指定过时期限 ,只要没有在设置 override-expire.
refresh_pattern语法:
refresh_pattern [-i] regexp min percent max [options]
min 参数是分钟数量.它是过时响应的最低时间限制.如果某个响应驻留在 cache 里的时间没有超过这个最低限制,那么它不会过期.类似的,max 参数是存活响应的最高时间限制.如果某个响应驻留在 cache 里的时间高于这个最高限制,那么它必须被刷新.
在最低和最高时间限制之间的响应,会面对 squid 的最后修改系数 LM-factor 算法 LM-factor=(response age)/(resource age).对这样的响应,squid 计算响应的年龄和最后修改系数,然后将它作为百分比值进行比较.响应年龄简单的就是从原始服务器产生,或最后一次验证响应后,经历的时间数量.源年龄在 Last-Modified 和 Date头 部之间是不同的.LM-factor 是响应年龄与源年龄的比率.这个基本不用详细了解,这是不是一个精确控制过期的参数,如果要精确控制过期,就不要使用这个.
refresh_pattern参数
我讲讲常用的几个参数的意思
override-expire
该选项导致 squid 在检查 Expires 之前,先检查 min 值.这样,一个非零的 min 时间让 squid 返回一个未确认的 cache 命中,即使该响应准备过期.
override-lastmod
改选项导致 squid 在检查 LM-factor 百分比之前先检查min ,它生效在expire 之后
reload-into-ims
该选项让 squid 在确认请求里,以 no-cache 指令传送一个请求.换句话说,squid 在转发请求之前,对该请求增加一个 If-Modified- Since 头部.注意这点仅仅在目标有 Last-Modified 时间戳时才能工作.外面进来的请求保留 no-cache 指令,以便它到达原始服务器.
一般情况可以使用 reload-into-ims.它其实是强行控制对象的超时时间,这违反了http协议的精神,但是在带宽较窄的场合,可以提高明显系统相应时间.
举例:
refresh_pattern -i \.css$ 1440 50% 129600 reload-into-ims refresh_pattern -i \.xml$ 1440 50% 129600 reload-into-ims refresh_pattern -i \.html$ 1440 90% 129600 reload-into-ims- refresh_pattern -i \.shtml$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.hml$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.jpg$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.png$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.gif$ 1440 90% 129600 ignore-reload refresh_pattern -i \.bmp$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.js$ 1440 90% 129600 reload-into-ims
ignore-reload
该选项导致 squid 忽略请求里的任何 no-cache 指令.
所以.如果希望内容一进入 cache 就不删除,直到被主动 purge 掉为止,可以加上 ignore-reload 选项,这个我们常用在mp3,wma,wmv,gif之类.
Examples:
refresh_pattern -i \.mp3$ 1440 50% 2880 ignore-reload refresh_pattern -i \.wmv$ 1440 50% 2880 ignore-reload refresh_pattern -i \.rm$ 1440 50% 2880 ignore-reload refresh_pattern -i \.swf$ 1440 50% 2880 ignore-reload refresh_pattern -i \.mpeg$ 1440 50% 2880 ignore-reload refresh_pattern -i \.wma$ 1440 50% 2880 ignore-reload
ignore-no-cache
该选项导致 Squid 强制忽略从源站而来的“Pragma: no-cache”和“Cache-control: no-cache”
ignore-private
该选项导致 Squid 强制忽略从源站而来的“Cache-control: private”
ignore-auth:强制将一个请求认为是源站发送的带有“Cache-control: public”
ignore-auth
该选项导致 Squid 强制将一个请求认为是源站发送的带有“Cache-control: public”
refresh_pattern percent 的计算
resource age =对象进入cache的时间-对象的last_modified
response age =当前时间-对象进入cache的时间
LM-factor=(response age)/(resource age)
举个例子,这里只考虑percent, 不考虑min 和max
例如:refresh_pattern 20%
假设源服务器上www.aaa.com/index.htm —–lastmodified 是 2007-04-10 02:00:00
squid上 proxy.aaa.com/index.htm index.htm进入cache的时间 2007-04-10 03:00:00
1)如果当前时间 2007-04-10 03:00:00
resource age =3点-2点=60分钟
response age =0分钟
index.htm还可以在cache停留的时间(resource age)*20%=12分钟
也就是说,index.htm进入cache后,可以停留12分钟,才被重新确认.
2)如果当前时间 2007-04-10 03:05:00
resource age =3点-2点=60分钟
response age =5分钟
index.htm还可以在cache停留的时间(resource age)*20%=12分钟-5=7
LM-factor=5/60=8.3%<20%
一直到2007-04-10 03:12:00 LM-factor=12/60=20% 之后,cache中的页面index.htm终于stale.
如果这时没有 index.htm 的请求,index.htm 会一直在缓存中,如果有 index.htm 请求,squid 收到该请求后,由于已经过期, squid 会向源服务器发一个 index.htm 是否有改变的请求,源服务器收到后,如果 index.htm 没有更新,squid 就不用更新缓存,直接把 缓存的内容放回给客户端,同时,重置对象进入 cache 的时间为与源服务器确认的时间,比如 2007-04-10 03:13:00,如果正好在这个后重新确认了页面.重置后,resource age 变长,相应在 cache 中存活的时间也变长.
如果有改变则把最新的 index.htm 返回给 squid,squid 收到会更新缓存,然后把新的 index.htm 返回给客户端,同时根据新页面 中的Last_Modified 和取页面的时间,重新计算 resource age,进一步计算出存活时间.
实际上,一个页面进入 cache 后,他的存活时间就确定了,即 (resource age) * 百分比,一直到被重新确认.
http://www.squid-cache.org/Doc/config/refresh_pattern/
Squid configuration directive refresh_pattern
Available in: 3.5 3.4 3.3 3.2 2.7 3.1 3.0 2.6
History:
- Changes in 3.3 refresh_pattern
-
stale-while-revalidate= not yet ported from 2.7
ignore-stale-while-revalidate= not yet ported from 2.7
negative-ttl= not yet ported from 2.7
- Changes in 3.2 refresh_pattern
-
New option max-stale= to provide a maximum staleness factor. Squid won't serve objects more stale than this even if it failed to validate the object.
Removed option ignore-no-cache. Its commonly desired behaviour is obsoleted by correct HTTP/1.1 Cache-Control:no-cache handling.
- Changes in 2.7 refresh_pattern
-
Several new options: stale-while-revalidate, ignore-stale-while-revalidate, max-stale, negative-ttl
Suggested defaults adjusted to match the changes in the cache directive.
For older versions see the linked page above
Configuration Details:
http://www.cnblogs.com/xiaojiu/p/3549042.html
1. http协议中关于过期的规定
由于http协议是支持缓存(cache)机制的,包括客户端浏览器的Cache(如ie的temporary internet files)以及web cache(如squid),这就决定了必须有一种机制使得这些被浏览器或squid缓存住的内容要定期更新。
对于内容的更新,一种方法是浏览器的功能来清除缓存,或者CDN的刷新系统来刷掉内容。这种做法的缺点是,需要人工干预。
另一种更新内容的方法就是通过http协议的过期机制来更新内容,这种过期机制是通过客户端的请求头与服务器端的响应头中的相关header来实现的。对于过期的内容,客户端或cache会向源站/上层cache发出验证的请求,如果在源站/上层cache上面这些内容已经改变过,客户端会重新获得这些内容。这种方法是本文要介绍的重点。
Date与Expires
Date和Expires都是表示绝对时间的概念,其不同点在于:
Date给出的是响应发出的绝对时间。
一个Date头域中的HTTP-date不应该是一个消息产生时刻之后的日期和时间。它应该表示与消息产生时的日期和时间的最近似值,除非没有办法产生一个合理的精确日期和时间。
Expires给出响应的内容过期的绝对时间。一个陈旧的缓存项不能被缓存(一个代理缓存或一个用户代理的缓存)返回给客户端,除非此缓存项被源服务器(或者被一个拥有实体的保鲜副本的中间缓存)验证。若响应包含一个Cache-Control 头域,并且含有max-age 缓存控制指令(参见14.9.3节),则此指令覆盖Expires头域。如果一响应包含一s-maxage缓存控制指令,那么对于一共享缓存(不能对私有缓存)来说,s-maxage指定的值将会覆盖max-age缓存控制指令或Expires头域。如果一响应包含一s-maxage缓存控制指令,那么对于一共享缓存(不能对私有缓存)来说,s-maxage指定的值将会覆盖max-age缓存控制指令或Expires头域。
Date与Expires通常是格林尼治标准时间(如果后面带有GMT),也就是比北京时间早8个小时。
请求:
max-age
表明客户端愿接受这样一个响应,此响应的年龄不大于客户端请求里max-age指定时间(以秒为单位)。除非max-stale缓存控制指令也包含在请求里,否则客户端是不能接收一个陈旧响应的。
min-fresh
表明客户端愿接受一个这样的响应,其保鲜寿命不小于响应当前年龄(current age,见13.2.3节关于current_age的定义)与客户端请求里的min-fresh指定的时间之和(以秒为单位)。也就是说,客户端想要一个响应至少在min-fresh指定的时间内是保鲜的。
Age与Cache-Control:max-age
age是指:自从这个响应在源站服务器上生成以来(而不是源站内容修改以来!!),到现在所经历的秒数。
max-age是指:一个响应被源站发出后,在cache当中存活的时间,换句话说,一个响应的Age值如果超过了max-age,就认为这个响应是过期的。
Age与max-age比Expires更加优先!
If-Modified-Since与Last-Modified
If-Modified-Since是http请求头的一部分,它表示客户端向源站询问“这个内容自从x年x月x日x时起,是否变过?”
如果源站发现该内容变过,则会返回一个200OK的响应,并把新的内容发回来给客户端。
如果源站发现内容没有变过,则会返回一个304的响应,告诉客户端“没有改变过,你的内容还是可以用的”,这种情况下就不用发送内容了,可以大大节省传输带宽。
注意:
如果客户端发的If-Modified-Since后面的日期是非法的日期,源站将直接返回200OK+新内容。If-Modified-Since后面跟的日期是客户端上一次接到的响应中,Last-Modified的值。
Last-Modified是响应头的一部分,是源站给出的,一个内容在源站上最终更新的时间。
对于静态内容,Last-Modified是文件的更新时间,对于动态内容,取决于源站的具体实现。
If-Unmodified-Sincey与Last-Modified
If-Unmodified-Since请求头域被用于一个方法使之成为条件方法。如果请求资源自从此头域指定时间开始之后没有改变,那么服务器应该执行此请求就像If-Unmodified-Since头域不存在一样。如果请求变量(variant,译注:见术语)在此头域指定时间后以后已经改变,那么服务器不能执行此请求,并且必须返回412(前提条件失败)状态码。
Etag与If-None-Match
有的时候,Last-Modified 与 If-Modified-Since不能够可靠地标示内容的改变,这就需要Etag等更加可靠的打标签的机制。Etag是响应头的一部分,是源站对内容所打的一个标签,用来标示这个文件,这个标签当且仅当内容变化才会变化,就像md5码一样。
与md5码不同的是,打Etag不需要读取整个文件的内容,比md5消耗的资源要少得多。Etag起到的作用跟Last-Modified差不多,都是标示内容的变化,只是比Last-Modified更可靠。
If-None-Match是请求头的一部分,它表示客户端向源站询问“这个内容的标签还是不是xxxxxx?”如果源站发现该内容变过,则会返回一个200OK的响应,并把新的内容发回来给客户端。如果源站发现内容没有变过,则会返回一个304的响应,告诉客户端“没有改变过,你的内容还是可以用的”,这种情况下就不用发送内容了,可以大大节省传输带宽。
如果If-None-Match头域里的任何实体标签(entity tag)假设与一个相似的GET请求(假设没有If-None-Match头域)返回实体的实体标签相匹配,或者,如果“*”被给出并且服务器关于那个资源的任何当前实体存在,那么服务器不能执行此请求方法,除非资源的修改日期和请求里If-Modified-Since头域(假设有的话)里提供的日期匹配失败(译注:匹配失败说明资源改变了)。换言之,如果请求方法是GET或HEAD,那么服务器应以304(没有改变)来响应,并且包含匹配实体的相关缓存头域(特别是Etag) 。对于所有其它方法,服务器必须以412(先决条件失败)状态码响应。
Etag与If-Match
如果If-Match头域里任何一个实体标签假设与一个相似GET请求(没有If-Match头域)返回响应里实体的实体标签相匹配,或者如果给出“*”并且请求资源的当前实体存在,那么服务器可以执行请求方法就好像If-Match头域不存在一样。
如果没有一个实体标签匹配,或者给出了“*”但服务器上没有当前的实体,那么服务器不能执
行此请求的方法,并且返回412响应(先决条件失败)。
http://blog.csdn.net/madun/article/details/18712621
refresh_pattern指令如下:
看论坛有人出现一个问题,就是当 Expires 设置为 60 秒以内时都不会 Cache ,但当设置成 61 秒时就能 Cache。
其实这不是个问题,在 Squid 中有这样一行配置 minimum_expiry_time 默认值是 60 。所以只需要修改这个值.就能实现 60 秒以内 Cache 了.
注意了,这个参数不要修改的过小,这个对时间的校准很严格的,设置太小,你传送过程中就花了 2 秒,你设置刚好 2 秒,过来就过期了,就样就没有用了。所以建议直接放在本地 cache 的前端,才设置小的时间。
这个参数主要目的也是上面写的,防止 cache 失效,然后不断 cache 的循环。
* percent与Min、Max两个值是完全没有关系
先理解什么情况下响应过期:
1.缓冲对象在squid的cache缓冲的时间大于refresh_pattern定义的max ,该响应过期;
2.缓冲对象在squid的cache缓冲的时间大于(原始数据进入squid的缓冲的时间-原始web数据所规定的Last-Modified时间)*percent,该响应过期;
override-expire
该选项导致squid在检查Expires头部之前,先检查min值。这样,一个非零的min时间让squid返回一个未确认的cache命中,即使该响应准备过期。
override-lastmod
改选项导致squid在检查LM-factor百分比之前先检查min值。
reload-into-ims
这个参数不是refresh_pattern中的参数,他是一个单独的参数.
在flashget和迅雷之类的软件,下载时发送http header时会包含下列信息:
Cache-Control:no-cache
Pragma:no-cache
这样的话squid主机接受这http header以后会让squid服务器直接连接web server取新的数据。这样对服务器很大的压力,
reload-into-ims参数的意思是将client请求的no-cache或reload请求转变成If-Modified-Since,而If-Modified-Since这个参数是用于判断文件是否被modified,这时squid和RS之间的数据传输仅仅只是验证文件是否更新或更改,如果RS返回的是文件未被更改,则直接由squid的cache文件返回给client,如果更改了,再到后端RS获取最新的文件并被squid缓存,这样做可以节省带宽,增加访问速度。
这个参数违反 HTTP 协议,但是对大部分网站来说是可以设置为 on 的,只要后端服务器对If-Modified-Since 头的判断正确即可。
大概意思是:只在源服务器上文件变动的情况下才实际更新cache当中的内容。
ignore-reload
1.不能通过 % squidclient -r http://www.lrrr.org/junk >/tmp/foo来强迫缓存响应更新
2.忽略浏览器的刷新操作(刷新操作会强迫squid调用新页面)
3.该选项导致squid忽略请求里的任何no-cache指令,会强行缓存.除非正常从squid过期(希望页面一进入cache就不删除,直到被主动purge掉为止)
ignore-no-cache
该选项处理http头部信息:
Pragma: no-cache
Cache-control: no-cache
ignore-no-store ignore-ridate
以上两个选项是为了处理http头部信息:
Cache-Control: no-store, must-ridate
Cache-Control: no-cache, must-ridate
ignore-no-cache ignore-private
处理http头部信息:Cache-Control: no-cache, must-ridate Pragma: no-cache
这两行是控制浏览器的缓存行为的,指示浏览器不得缓存
以上两个参数就是为了处理动态文件不能被缓存的问题.
eg:
refresh_pattern -i \.jpg$ 180 90% 1440 reload-into-ims ignore-no-cache
refresh_pattern -i http://xxx/jobs_nv/ajax_keywords.asp 1440 50% 10080 override-expire override-lastmod reload-into-ims ignore-reload ignore-no-cache ignore-private
第一个例子是缓存jpg,第二个例子是缓存动态文件asp
ignore-reload和reload-into-ims的区别:
ignore-reload 会强行缓存,对no-cache当没有见到,但使用 reload-into-ims,当有no-cache的请求发过来时,他会发一个http头部回去问源服务器(上层服务器),是否有修改,如果修改就更新,如果没有就返回给客户.
regexp参数是大小写敏感的正则表达式。你可以使用-i选项来使它们大小写不敏感。squid按顺序来检查refresh_pattern行;当正则表达式之一匹配URI时,它停止搜索。
理解squid检查不同值的顺序非常重要。如下是squid的refresh_pattern算法的简单描述:
假如响应年龄超过refresh_pattern的max值,该响应过期;
假如LM-factor少于refresh_pattern百分比值,该响应存活;
假如响应年龄少于refresh_pattern的min值,该响应存活;
其他情况下,响应过期。
在squid.conf.default里面,refresh_pattern参数下面的注释是这样的:
TAG: refresh_pattern
usage: refresh_pattern [-i] regex min percent max [options]
Basically a cached object is:
FRESH if expires < now, else STALE
STALE if age > max
FRESH if lm-factor < percent, else STALE
FRESH if age < min
else STALE
以上所有的时间都是以分钟为单位计算。
· refresh_pattern指出的缓冲对象过期了,这个对象过期。
· refresh_pattern指出的缓冲对象在squid的cache缓冲的时间大于max的话,这个对象过期。
· refresh_pattern指出的缓冲对象的lm-factor大于等于percent的话,这个对象过期。
· refresh_pattern指出的缓冲对象在squid的cache缓冲的时间小于min的话,这个对象不过期。
可是,这个lm-factor到底是怎么算的?有什么具体意义? look下面的图:
上面这张图来自于《Squid.Definitive.Guide》第七章,对squid的LM-factor算法作出了一个很直观的描述。
请注意这张图的起始时间坐标:Last-Modified,这个是由squid读取的原始web数据所规定的。
然后就是Date,这个是原始数据进入squid的缓冲的时间。
最后就是Expires,这个就是原始数据在squid中的缓冲过期时间。
可以很容易的得出结论,对于LM-factor算法来说,原始数据在squid中的缓冲时间为
(原始数据进入squid的缓冲的时间-原始web数据所规定的Last-Modified时间)*percent
所以,我们可以郑重得出结论,在squid的refresh_pattern设置中,percent与Min、Max两个值是完全没有关系!
最后总结一下,对于squid来说,缓冲的数据在cache中的存活时间是这样决定的:
如果有定义refresh_pattern:只要满足以下两个条件之一,缓冲对象过期
缓冲对象在squid的cache缓冲的时间大于refresh_pattern定义的max
缓冲对象在squid的cache缓冲的时间大于(原始数据进入squid的缓冲的时间-原始web数据所规定的Last-Modified时间)*percent
如果符合多个refresh_pattern定义,以第一条符合定义的refresh_pattern为准
如果没有符合定义的refresh_pattern,则按squid的默认处理规则
Squid 反向代理一般只缓存可缓冲的数据(比如 html 网页和图片等),而一些 CGI 脚本程序或者 ASP、JSP 之类的动态程序默认不缓存。它根据从 WEB 服务器返回的 HTTP 头标记来缓冲静态页面。有四个最重要 HTTP 头标记:
Last-Modified: 告诉反向代理页面什么时间被修改
Expires: 告诉反向代理页面什么时间应该从缓冲区中删除
Cache-Control: 告诉反向代理页面是否应该被缓冲
Pragma: 用来包含实现特定的指令,最常用的是 Pragma:no-cache
例如:http://bbs.linuxtone.org/viewthread.php?tid=138
refresh_pattern 20%
假设源服务器上www.aaa.com/index.htm -----lastmodified 是 2007-04-10 02:00:00
squid上 proxy.aaa.com/index.htm index.htm进入cache的时间 2007-04-10 03:00:00
1)如果当前时间 2007-04-10 03:00:00 也就是说squid刚刚缓存上
源年龄 =3点-2点=60分钟 对象进入cache的时间 - 页面自身修改时间
响应年龄 =0分钟 当前时间- 对象进入cache的时间
index.htm还可以在cache停留的时间(源年龄)*20%=12分钟
也就是说,index.htm进入cache后,可以停留12分钟,才被重新确认。
2)如果当前时间 2007-04-10 03:05:00 也就是说squid已缓存了5分钟
源年龄 =3点-2点=60分钟
响应年龄 =5分钟
index.htm还可以在cache停留的时间(源年龄 )* 20% - 响应年龄 = 12分钟-5分钟=7分钟
LM-factor=响应年龄/源年龄=5/60=8.3%<20%
一直到2007-04-10 03:12:00 LM-factor=12/60=20% 之后,cache中的页面index.htm终于stale。
如果这时没有index.htm的请求,index.htm会一直在缓存中,如果有index.htm请求,squid收到该请求后,由于已经过期, squid会向源服务器发一个index.htm是否有改变的请求,源服务器收到后,如果index.htm没有更新,squid就不用更新缓存,直接把缓存的内容放回给客户端,同时,重置对象进入cache的时间为与源服务器确认的时间,比如2007-04-10 03:13:00,如果正好在这个后重新确认了页面。重置后,resource age变长,相应在cache中存活的时间也变长。
如果有改变则把最新的index.htm返回给squid,squid收到会更新缓存,然后把新的index.htm返回给客户端,同时根据新页面中的Last_Modified和取页面的时间,重新计算resource age,进一步计算出存活时间。
实际上,一个页面进入cache后,他的存活时间就确定了,即 (resource age) * 百分比,一直到被重新确认。
# NETWORK OPTIONS(网络选项)
# -----------------------------------------------------------------------------
icp_port 3130 #icp端口
# OPTIONS WHICH AFFECT THE NEIGHBOR SELECTION ALGORITHM
#-----------------------------------------------------------------------------
hierarchy_stoplist cgi-bin ?
hierarchy_stoplist -i ^https:\\ ?
acl QUERY urlpath_regex -i cgi-bin \? \.asp \.php \.jsp \.cgi
acl denyssl urlpath_regex -i ^https:\\
no_cache deny denyssl
#asp、cgi、php等动态脚本也不要缓存,
#https://开通的不缓存是因为一般我们进行电子商务交易,
#例如银行付款等都是采用这个的,如果把信用卡号什么缓存那不是很危险。
# OPTIONS WHICH AFFECT THE CACHE SIZE(定义cache大小的选项)
# -----------------------------------------------------------------------------
cache_swap_high 95 #最高缓存百分比,就是上面那个额外内存的使用百分比
ipcache_size 1024
ipcache_low 90
ipcache_high 95
fqdncache_size 1024
# -----------------------------------------------------------------------------
# 各发行版自带的Squid略有区别,一般使用各发行版自带的设置
# <cache_dir>; <aufs|ufs>; <目录所在>; <MBytes大小>; <dir1>; <dir2>;
# 那个 aufs 只有在编译的时候加入 --enable-async-io 那个选项才有支持,
# 至于目录所在地与所占用的磁盘大小则请视您的主机情况而定,
# 而后面 dir1, dir2 则是两个次目录的大小,通常 16 256 或 64 64 皆可,
# 一般来说,数字最好是 16 的倍数,据说性能会比较好啦!
cache_dir aufs /Cache2 100 16 256
#cache_access_log /usr/local/squid/var/logs/access.log
#cache_log /usr/local/squid/var/logs/cache.log
#cache_store_log /usr/local/squid/var/logs/store.log
#pid_filename /usr/local/squid/var/logs/squid.pid
# -----------------------------------------------------------------------------
# 各发行版自带的Squid略有区别,一般使用各发行版自带的设置
# TAG: ftp_user
ftp_user Squid@ #用户名
ftp_passive on #被动模式
#认证
#auth_param basic children 5
#auth_param basic realm Squid proxy-caching web server
#auth_param basic credentialsttl 2 hours
#auth_param basic casesensitive off
# -----------------------------------------------------------------------------
# TAG: refresh_pattern Cache更新时间设置
#<refresh_pattern>; <regex>; <最小时间>; <百分比>; <最大时间>;
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern . 0 20% 4320
#如果proxy 再次取用这个档案时,则 cache 内的数据会被更新!
# -----------------------------------------------------------------------------
#连接到其他机器的最大尝试时间
connect_timeout 1 minute
peer_connect_timeout 30 seconds
request_timeout 2 minutes
persistent_request_timeout 1 minute
# -----------------------------------------------------------------------------
#acl myexample dst_as 1241
#acl password proxy_auth REQUIRED
#acl fileupload req_mime_type -i ^multipart/form-data$
#acl javascript rep_mime_type -i ^application/x-javascript$
#
#Recommended minimum configuration:
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443 563
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 563 # https, snews
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
acl msn url_regex -i ^[url]http://gateway.messenger.hotmail.com[/url]
acl inside1 src 192.168.1.0/24 #内部网IP段
acl inside2 src 192.168.2.0/24
acl localmac arp "/usr/local/squid/localmac" #mac地址文件
http_access allow inside1 #允许inside1规则通过
http_access allow inside2 #允许inside2规则通过
http_access allow localmac #允许localmac里面有登记的mac地址通过
http_access allow msn #允许访问[url]http://gateway.messenger.hotmail.com[/url]
http_access allow admin #允许00:40:05:13:C4:B2这个mac地址
#Recommended minimum configuration:
#
# Only allow cachemgr access from localhost
http_access allow manager localhost #允许manager访问localhost
http_access deny manager #禁止manager访问
# Deny requests to unknown ports
http_access deny !Safe_ports #禁止访问不在Safe_ports里的端口
# Deny CONNECT to other than SSL ports
http_access deny CONNECT !SSL_ports #禁止访问非443,563端口
#
acl worktime time MTWHF 8:30-12:00 14:00-18:00
acl mmxfile urlpath_regex -i \.mp3$ \.avi$ \.rmvb$ \.rm$ \.wma$ \.wmv$
http_access deny worktime mmxfile #禁止在worktime时间内访问.mp3,.avi,.rmvb,.rm,.wma文件
http_access deny worktime banned_sites #banned.list文件里的网址全部丢弃
http_access allow localhost #localhost可以访问
acl loc1 src 192.168.1.0/24
acl loc1_conn maxconn 50
acl loc2 src 192.168.2.0/24
acl loc2_conn maxconn 30
http_access allow loc1
http_access deny loc2 src loc2_conn
http_access allow loc2
#-----------------------------
http_access deny all #丢弃其他
# HTTPD-ACCELERATOR OPTIONS(HTTPD加速选项)
# -----------------------------------------------------------------------------
#设定透明代理
httpd_accel_host virtual #主机名
httpd_accel_port 80 #透明代理端口
httpd_accel_with_proxy on
httpd_accel_uses_host_header on
Squid 中 refresh_pattern 的作用
用于确定一个页面进入cache后,它在cache中停留的时间.refresh_pattern 规则仅仅应用到没有明确过时期限的响应.原始服务器能使 用 Expires 头部,或者 Cache-Control:max-age 指令来指定过时期限 ,只要没有在设置 override-expire.
语法:
1
|
refresh_pattern [-i] regexp min percent max [options] |
min 参数是分钟数量.它是过时响应的最低时间限制.如果某个响应驻留在 cache 里的时间没有超过这个最低限制,那么它不会过期.类似的,max 参数是存活响应的最高时间限制.如果某个响应驻留在 cache 里的时间高于这个最高限制,那么它必须被刷新.
在最低和最高时间限制之间的响应,会面对 squid 的最后修改系数 LM-factor 算法 LM-factor=(response age)/(resource age).对这样的响应,squid 计算响应的年龄和最后修改系数,然后将它作为百分比值进行比较.响应年龄简单的就是从原始服务器产生,或最后一次验证响应后,经历的时间数量.源年龄在 Last-Modified 和 Date头 部之间是不同的.LM-factor 是响应年龄与源年龄的比率.这个基本不用详细了解,这是不是一个精确控制过期的参数,如果要精确控制过期,就不要使用这个.
Refresh_pattern 有14个参数
我讲讲常用的几个参数的意思
override-expire
该选项导致 squid 在检查 Expires 之前,先检查 min 值.这样,一个非零的 min 时间让 squid 返回一个未确认的 cache 命中,即使该响应准备过期.
override-lastmod
改选项导致 squid 在检查 LM-factor 百分比之前先检查min ,它生效在expire 之后
reload-into-ims
该选项让 squid 在确认请求里,以 no-cache 指令传送一个请求.换句话说,squid 在转发请求之前,对该请求增加一个 If-Modified- Since 头部.注意这点仅仅在目标有 Last-Modified 时间戳时才能工作.外面进来的请求保留 no-cache 指令,以便它到达原始服务器.
一般情况可以使用 reload-into-ims.它其实是强行控制对象的超时时间,这违反了http协议的精神,但是在带宽较窄的场合,可以提高明显系统相应时间.
举例:
01
02
03
04
05
06
07
08
09
10
|
refresh_pattern -i \.css$ 1440 50% 129600 reload-into-ims refresh_pattern -i \.xml$ 1440 50% 129600 reload-into-ims refresh_pattern -i \.html$ 1440 90% 129600 reload-into-ims- refresh_pattern -i \.shtml$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.hml$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.jpg$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.png$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.gif$ 1440 90% 129600 ignore-reload refresh_pattern -i \.bmp$ 1440 90% 129600 reload-into-ims refresh_pattern -i \.js$ 1440 90% 129600 reload-into-ims |
ignore-reload
该选项导致 squid 忽略请求里的任何 no-cache 指令.
所以.如果希望内容一进入 cache 就不删除,直到被主动 purge 掉为止,可以加上 ignore-reload 选项,这个我们常用在mp3,wma,wmv,gif之类.
Examples:
1
2
3
4
5
6
|
refresh_pattern -i \.mp3$ 1440 50% 2880 ignore-reload refresh_pattern -i \.wmv$ 1440 50% 2880 ignore-reload refresh_pattern -i \. rm $ 1440 50% 2880 ignore-reload refresh_pattern -i \.swf$ 1440 50% 2880 ignore-reload refresh_pattern -i \.mpeg$ 1440 50% 2880 ignore-reload refresh_pattern -i \.wma$ 1440 50% 2880 ignore-reload |
ignore-no-cache
该选项导致 Squid 强制忽略从源站而来的“Pragma: no-cache”和“Cache-control: no-cache”
ignore-private
该选项导致 Squid 强制忽略从源站而来的“Cache-control: private”
ignore-auth:强制将一个请求认为是源站发送的带有“Cache-control: public”
ignore-auth
该选项导致 Squid 强制将一个请求认为是源站发送的带有“Cache-control: public”
Refresh_pattern percent 的计算
resource age =对象进入cache的时间-对象的last_modified
response age =当前时间-对象进入cache的时间
LM-factor=(response age)/(resource age)
举个例子,这里只考虑percent, 不考虑min 和max
例如:refresh_pattern 20%
假设源服务器上www.aaa.com/index.htm —–lastmodified 是 2007-04-10 02:00:00
squid上 proxy.aaa.com/index.htm index.htm进入cache的时间 2007-04-10 03:00:00
1)如果当前时间 2007-04-10 03:00:00
resource age =3点-2点=60分钟
response age =0分钟
index.htm还可以在cache停留的时间(resource age)*20%=12分钟
也就是说,index.htm进入cache后,可以停留12分钟,才被重新确认.
2)如果当前时间 2007-04-10 03:05:00
resource age =3点-2点=60分钟
response age =5分钟
index.htm还可以在cache停留的时间(resource age)*20%=12分钟-5=7
LM-factor=5/60=8.3%<20%
一直到2007-04-10 03:12:00 LM-factor=12/60=20% 之后,cache中的页面index.htm终于stale.
如果这时没有 index.htm 的请求,index.htm 会一直在缓存中,如果有 index.htm 请求,squid 收到该请求后,由于已经过期, squid 会向源服务器发一个 index.htm 是否有改变的请求,源服务器收到后,如果 index.htm 没有更新,squid 就不用更新缓存,直接把 缓存的内容放回给客户端,同时,重置对象进入 cache 的时间为与源服务器确认的时间,比如 2007-04-10 03:13:00,如果正好在这个后重新确认了页面.重置后,resource age 变长,相应在 cache 中存活的时间也变长.
如果有改变则把最新的 index.htm 返回给 squid,squid 收到会更新缓存,然后把新的 index.htm 返回给客户端,同时根据新页面 中的Last_Modified 和取页面的时间,重新计算 resource age,进一步计算出存活时间.
实际上,一个页面进入 cache 后,他的存活时间就确定了,即 (resource age) * 百分比,一直到被重新确认.
http://blog.csdn.net/pytanght/article/details/38307491
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命中
http://blog.sina.com.cn/s/blog_517e2e1b0100ff0d.html
http://zlbzhu.blog.51cto.com/1413424/770445