公司的网站使用Squid 2.6STABLE2作缓存加速服务器,缓存的命中率一直不好,最好也只能达到90%,折腾了许久,终于发现影响最大的原来只是一个小参数,不过期间也学 到了不少东西~
起初,考虑缓存命中率不高,考虑是不是给Squid的内存不够,所以就加大了内存配置,2G内存的机器给Squid 1G用,测试了两天,结果基本没有什么大的改变;于是调整refresh_pattern的参数,增大内容缓存时间,测试了两天,效果也不理想。
从 kxn的文章中知道可以使用Expires模块让Apache给文件指定缓存时间,期望可以提高缓存性能,于是在服务器上:
ExpiresActive On
ExpiresDefault A2592000
结果第二天一早发现缓存命中率竟然比前一天还下降了2个百本点,有点晕了~
于是将cachemgr配置起来,详细地检查squid的运行状况,发现1G的内存缓存实际只用了不到300M,所以显然不是内存不够的问题。
为了充分利用内存,将maximum_object_size_in_memory调大到128KB,让其可以缓存更大的文件,而不是默认的 8KB。顺手将ufs换成aufs,启用异步IO。
之后情况稍有改善,1个小时之后,内存的占用达到了1G,但命中率并没有明显上升。
于是又调整了内存的覆盖策略(memory_replacement_policy),听从kxn的教诲,使用lru,发现变化不大,也许是我们的 访问量还不大的原因吧。
这时候缓存命中率仍然在90%以下徘徊。是不是我们的网站结构影响只能达到这么高呢?但是网站结构我没有办法改变,所以还是要从其他方面入手来解决 问题。
于是使用Cache Manager 仔细的查看各个统计数据,当看到In-Memory and In-Transit Objects项目时,发现一个问题,那就是所有的网页文件都显示NOT_IN_MEMORY,这就比较奇怪了,问什么访问量最大的网页文件竟然没有被缓 存到内存呢?是因为文件太大还是因为文件请求的数量太少,所以才没有被缓存呢?于是找了一个页面作测试,使用工具查看了返回的大小,只有40K多一些,与 我的maximum_object_size_in_memory最大值128KB还有相当大的差距,所以不可能是这个原因。于是有使用ab程序对这个页 面做了1000次请求,心想这下总会缓存了吧。可是查看缓存内容,依然没有,而且不但内存中没有,就连硬盘上也没有!
至此得出结论,一定是什么原因阻止了Squid对这些网页进行缓存。仔细的检查In-Memory and In-Transit Objects中的内容,发现IN_MEMORY 状态的对象基本都是jpg和gif图像文件,html,css等文本文件内容则都没有缓存。
这两种文件有什么不同吗?记忆中Squid也没有对这些文件类型的设定呀,refresh_pattern对所有的静态文件的设置也都是一致的,所 以差异不应该来源于squid本身——也就是因为这种记忆使得我后来多费了许多的功夫~
在Apache上找到了文本文件与图像文件之间设置的差异——deflate压缩。是不是所有使用deflate压缩的内容都不会缓存呢?使用同样 的squid软件版本及配置文件,相同的Apache软件版本和配置,快速的搭建了一套测试环境。squid只有1台,重建其磁盘缓冲区,重新启动 squid,观察内存中对象的变化。果然,对于deflate压缩的内容,squid内存中没有缓存,磁盘也找不到。停止apache的deflate功 能,重新请求页面,立即在squid的内存中查到了内容的缓存,这么看来是squid和deflate不太兼容了?
好吧,先将产品环境Apache的deflate停掉,过了一段时间,有两台squid的缓存命中了提高到了94%,虽然只提升了4个百分点,但是 这充分验证了squid和deflate不兼容的观点。
然而,事情到此才刚刚开始!
难道Squid真的无法缓存deflate压缩的页面吗?好吧google一下,squid+deflate,在squid的邮件列表中找到了一些 讨论deflate的东西,属于比较古老的吧,说因为deflate压缩之后,会产生Content-Encoding: gzip这样的HTTP头部,属于HTTP/1.1的内容,而Squid并不完全兼容HTTP/1.1之类的,需要用Transfer-Encoding 之类的代替,可是mod_deflate和mod_gzip产生的头部就是Content-Encoding,怎么办?
为了解决这个问题,引入了另一个Apache的模块,mod_headers,用它来改写HTTP应答的头部,将Content-Encoding 更改给Transfer-Encoding,可是,很自然的,页面一片乱码!说明此路不通啊!
又以Content-Encoding为关键字,快速的搜索了一下squid 2.6STABLE2的源代码,也没有发现几个地方用到这个东西,无果。
继续Google之,squid+can’t cache+Content-Encoding找到一篇文章,其中说’SQUID would never bother to cache ANYTHING that had
a “Vary:” header on it.’ 看来Squid缓存内容与Vary: 头部有关系。再次检查一下HTTP请求返回的头部内容,发现对于deflate压缩的内容,拥有”Vary: Accept-Encoding”这样一个头部,而没有经过deflate压缩的内容则没有这个头部,这次看来问题比较清楚了,因为deflate压缩添 加了Vary: Accept-Encoding这个头部,导致了内容无法被squid缓存。
那么难道真的没有办法让squid缓存deflate压缩之后的内容吗?
基于上面的经验,很自然的想到使用mod_headers模块的功能将Vary头抹掉Squid不就可以缓存了吗?后来一想,这样会有其它问题: 1)如果用户浏览器不支持gzip压缩功能,那么将无法正常的浏览网页;2)其它可能很重要的Vary内容也没有了,可能会导致更大的隐患。那么这种办法 不行。
还有其它的办法吗?再次的快速搜索了Squid的源文件中关于Vary的内容,在Changelog中找到了这么一条:
- Full ETag/Vary support, caching responses which varies with request details (browser, language etc).
也就是说已经完全支持带ETag/Vary头部的内容缓存了。这一条出现在Changes to squid-2.6.STABLE1,也就是说在Squid2.6STABLE1就已经完全实现了这个功能,那么2.6STABLE2应该没有问题,会不 会是2.6STABLE2的BUG呢,查询了一下2.6系列的所有Changelog,没有提到此故障的信息。推断我们的故障要么由一个未知BUG导致, 要么是自己配置不当。BUG的问题我无法确认,只能先从配置入手。
找来一份2.6STABLE2带的默认配置文件,搜索Vary,第一条:
# TAG: cache_vary
# Set to off to disable caching of Vary:in objects.
#
#Default:
# cache_vary on
难道我的配置文件是off不成?赶紧检查,发现还真是off,sign,原来就是这个问题折磨我,改成on,将 Apache的Deflate配置启用,再观察内存对象,发现静态网页真的被缓存了!
郁闷了许久,终于可以松口气了。
过了一会儿,再查看Squid的状态,发现缓存命中率没有下降,稳定在94%左右。
也许Squid还有什么可挖掘的空间吧,改天接着折腾!
后记:Squid对Vary和Etag的支持属于2.6的一项主要改进,这一特性改进Squid对HTTP/1.1标准的支持。在将Squid升级 至2.6之前,也看过他的Changelog,但当时并不明白Vary到底有什么用途,这么一折腾,明白了不少。看来应该把HTTP/1.1的标准再好好 研读一下。
转
访问控制
访问控制元素
ACL元素是Squid的访问控制的基础。基本的ACL元素语法如下:
acl name type value1 value2 ...例如:
acl Workstations src 10.0.0.0/16
acl Http_ports port 80 8000 8080 基本的ACL类型
IP地址
使用对象:src,dst,myip
squid在ACL里指定IP地址时,能以子网,地址范围,域名等形式编写地址。假如你忽略掩码,squid会自动计算相应的掩码。如下: acl Foo src 127.0.0.1/32,通过指定地址范围做到列举多个相邻子网。例如:acl Bar src 172.16.10.0-172.16.19.0/24. 注意使用IP地址范围,掩码只能取一个。也能在IP ACL里指定主机名,启动时,将主机名转换成IP地址。(一旦启动,squid不会对主机名的地址发起第二次DNS查询。这样,假如在squid运行中地址已改变,squid不会注意到)。假如主机名被解析成多个IP地址,squid将每一个增加到ACL里。注意你也可以对主机名使用网络掩码。
ACL主机名转换到IP地址的过程会延缓squid的启动。除非绝对必要,请在src,dst,和myip ACL里避免使用主机名。
squid以一种叫做splay tree的数据结构在内存里存储IP地址ACL。splay tree有自我调整的特性,其中之一是在查询发生时,列表会自动纠正它自己的位置。当某个匹配元素在列表里发现时,该元素变成新的树根。在该方法中,最近参考的条目会移动到树的顶部,这减少了将来查询的时间。
属于同一ACL元素的所有的子网和范围不能重迭。例如,如下不被允许:
acl Foo src 1.2.3.0/24 acl Foo src 1.2.3.4/32它导致squid在cache.log里打印警告:
域名
使用对象:srcdomain,dstdomain,和cache_host_domain指令
当ACL域名以"."开头,squid将它作为通配符,相反,如果ACL域名不以"."开头,squid使用精确的字符串比较。squid使用splay tree的数据结构来存储域名ACL.
用户名
使用对象:ident,proxy_auth
用户名必须被严格匹配。squid也有相关的ACL对用户名使用正则表达式匹配(ident_regex和proxy_auth_regex)。你可以使用单词"REQUIRED"作为特殊值去匹配任意用户名。
正则表达式
使用对象:srcdom_regex, dstdom_regex, url_regex, urlpath_regex, browser, referer_regex, ident_regex, proxy_auth_regex, req_mime_type, rep_mime_type
大量的ACL使用正则表达式来匹配字符串。最常使用的正则表达式功能用以匹配字符串的开头或结尾。例如,^字符匹配行或字符串的开头,$是匹配行或字符串的结尾,.字符是匹配任意单个字符的通配符,对所有的squid正则表达式类,匹配是默认大小写敏感的。为了大小写不敏感,在ACL类型后面使用-i选项。
TCP端口号
使用对象:port,myport
该类型是相对的,值是个别的端口号或端口范围。如下示例:
acl Foo port 123 acl Bar port 1-1024自主系统号
使用对象:src_as,dst_as
Internet路由器使用自主系统(AS)号来创建路由表。基本上,某个AS号指向被同一组织管理的IP网络范围。例如,我的ISP分配了如下网络块:134.116.0.0/16, 137.41.0.0/16, 206.168.0.0/16,和其他更多。在Internet路由表里,这些网络被公布为属于AS 3404。当路由器转发包时,它们典型的选择经过最少AS的路径。AS基础的ACL仅仅被网络gurus使用。
ACL类型
src
使用IP地址来控制客户允许或不允许访问Squid。src类型指客户源IP地址。
acl MyNetwork src 192.168.0.0 10.0.1.0/24 10.0.5.0/24 172.16.0.0/12
dst
dst类型指向原始服务器(目标)IP地址。在某些情况下,能使用该类型来阻止用户访问特定web站点。然而,在使用dst ACL时须谨慎。大部分squid接受到的请求有原始服务器主机名.
请注意,为了避免延时,该尽可能的使用dstdomain ACL类型来代替dst, dst ACL存在的问题是,你试图允许或拒绝访问的原始服务器可能会改变它的IP地址。假如你不关心这样的改变,那就不必麻烦去升级squid.conf。你可以在acl行里放上主机名,但那样会延缓启动速度。假如你的ACL需要许多主机名,你也许该预处理配置文件,将主机名转换成IP地址。
myip
myip类型指Squid的IP地址,它被客户连接。所以该ACL元素仅仅当系统有多个IP地址时才有用。
请注意,使用该机制你必须特别小心,阻止来自某个子网的用户连接squid位于另一子网的IP地址。否则,在会计和市场子网的聪明的用户,能够通过技术部子网进行连接,从而绕过你的限制。
dstdomain
使用它们去阻塞对某些站点的访问,去控制squid如何转发请求,以及让某些响应不可缓存,如下两行的不同:
acl A dst www.squid-cache.org acl B dstdomain www.squid-cache.orgA实际上是IP地址ACL,假如在squid运行时IP地址改变了,squid会继续使用旧的地址。然而dstdomain ACL以域名形式存储,并非IP地址。当squid检查ACL B时,它对URL的主机名部分使用字符串比较功能,它并不真正关心是否www.squid-cache.org的IP地址改变了。
使用dstdomain ACL的主要问题是某些URL使用IP地址代替主机名。
srcdomain
srcdomain要求对每个客户IP地址进行所谓的反向DNS查询。使用dst ACL,FQDN查询会导致延时。请求会被延缓处理直到FQDN响应返回。FQDN响应被缓存下来,所以srcdomain查询通常仅在客户首次请求时延时。srcdomain查询有时不能工作。许多组织并没有保持他们的反向查询数据库与日更新,在该情形下,请求可能会延时非常长时间,直到DNS查询超时。
假如你使用srcdomain ACL,请确认你自己的DNS in-addr.arpa区域配置正确并且在工作中。port
使用port ACL来限制对某些原始服务器端口号的访问,port ACL允许你定义单独的端口或端口范围。例如:acl HTTPports port 80 8000-8010 8080
myport
port ACL指向原始服务器的端口号,myport指向squid自己的端口号,用以接受客户请求。假如在http_port指令里指定不止一个端口号,那么squid就可以在不同的端口上侦听。
假如将squid作为站点HTTP加速器和用户代理服务器,可以在80上接受加速请求,在3128上接受代理请求。想让所有人访问加速器,但仅仅你自己的用户能以代理形式访问squid。ACL可能如下:
acl AccelPort myport 80 acl ProxyPort myport 3128 acl MyNet src 172.16.0.0/22 http_access allow AccelPort # anyone http_access allow ProxyPort MyNet # only my users http_access deny ProxyPort # deny othersmethod
method ACL指HTTP请求方法,如:acl Uploads method PUT POST.
Squid知道下列标准HTTP方法:GET, POST, PUT, HEAD, CONNECT, TRACE, OPTIONS和DELETE。另外,来自WEBDAV规范,RFC 2518的方法:PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK。还有非标准的WEBDAV方法: BMOVE, BDELETE, BPROPFIND。最后,你可以在extension_methods指令里配置squid去理解其他的请求方法。
注意CONNECT方法非常特殊。它是用于通过HTTP代理来封装某种请求的方法。在处理CONNECT方法和远程服务器的端口号时应特别谨慎。如你不希望squid连接到某些远程服务。你该限制CONNECT方法仅仅能连接到HTTPS/SSL或NNTPS端口(443和563)。默认的squid.conf这样做:
acl CONNECT method CONNECT acl SSL_ports 443 563 http_access allow CONNECT SSL_ports http_access deny CONNECT在该配置里,squid仅仅允许加密请求到端口443(HTTPS/SSL)和563(NNTPS)。CONNECT方法对其他端口的请求都被拒绝。
PURGE是另一个特殊的请求方法。它是Squid的专有方法,它让管理员能强制删除缓存对象。
proto
该类型指URI访问(或传输)协议。有效值:http, https (same as HTTP/TLS), ftp, gopher, urn, whois, 和cache_object。例如拒绝所有的FTP请求:
acl FTP proto FTP http_access deny FTPcache_object机制是squid的特性。它用于访问squid的缓存管理接口。默认的squid.conf文件有许多行限制缓存管理访问:
acl Manager proto cache_object acl Localhost src 127.0.0.1 http_access allow Manager Localhost http_access deny Manager这些配置行仅允许来自本机地址的缓存管理请求,所有其他的缓存管理请求被拒绝。这意味着在squid机器上有帐号的人,能访问到潜在的敏感缓存管理信息。
time
time ACL允许你控制基于时间的访问,时间为每天中的具体时间,和每周中的每天。日期以单字母来表示,见如下表。时间以24小时制来表示。开始时间必须小于结束时间。
Code
Day
S
Sunday
M
Monday
T
Tuesday
W
Wednesday
H
Thursday
F
Friday
A
Saturday
D
All weekdays (M-F)
日期和时间由localtime()函数来产生。
时间跨越子夜,你需要把它们分成两个ACL来写,或者使用否定机制来定义非忙时。例如:
acl Offpeak1 20:00-23:59 acl Offpeak2 00:00-04:00 http_access allow Offpeak1 ... http_access allow Offpeak2 ...另外,你可以这样写:
acl Peak 04:00-20:00 http_access allow !Peak ...不应该在同一个time ACL里放置多个日期和时间范围列表。例如,假如你输入:acl Blah time M 08:00-10:00 W 09:00-11:00,实际能做到的是:acl Blah time MW 09:00-11:00,解析仅仅使用最后一个时间范围。正确的写法是,将它们写进两行:
acl Blah time M 08:00-10:00 acl Blah time W 09:00-11:00ident
ident ACL匹配被ident协议返回的用户名。
ident ACL可以对你的用户请求造成延时,推荐仅仅在本地局域网中,并且大部分客户工作站运行ident服务时,才使用ident ACL。
注意ident协议不是很安全;squid也有个对客户端执行懒惰ident查询。在该情形下,在等待ident查询时,请求不会延时。
proxy_auth
squid支持HTTP代理验证功能。使用代理验证,客户的包括头部的http请求包含了验证信用选项。squid解密信用选项,并调用外部验证程序以发现该信用选项是否有效。
squid当前支持三种技术以接受用户验证:HTTP基本协议,数字认证协议,和NTLM。基本认证是非常不安全的技术,以明文同时发送。数字认证更安全,但也更复杂。NTLM也比基本认证更安全,然而它是Microsoft发展的专有协议。
为了使用代理验证,你必须配置squid使用大量的外部辅助程序,auth_param指令控制对所有辅助程序的配置。
auth_param指令和proxy_auth ACL是少数在配置文件里顺序重要的实例。你必须在proxy_auth ACL之前定义至少一个验证辅助程序(使用auth_param)。代理验证不支持HTTP拦截,因为用户代理不知道它在与代理服务器,而非原始服务器通信。
src_as
该类型检查客户源IP地址所属的具体AS号。例如,我们虚构某ISP使用AS 64222并且通告使用10.0.0.0/8,172.16.0.0/12,192.168.0.0/16网络。你可以编写这样的ACL,它允许来自该ISP地址空间的任何主机请求:
acl TheISP src 10.0.0.0/8 acl TheISP src 172.16.0.0/12 acl TheISP src 192.168.0.0/16 http_access allow TheISP当然,可以这样写:
acl TheISP src_as 64222 http_access allow TheISPdst_as
dst_as ACL经常与cache_peer_access指令一起使用。在该方法中,squid使用与IP路由一致的方式转发cache丢失。
snmp_community
snmp_community ACL对SNMP查询才有意义,后者被snmp_access指令控制。例如:
acl OurCommunityName snmp_community hIgHsEcUrItY acl All src 0/0 snmp_access allow OurCommunityName snmp_access deny All在该情况中,假如community名字设置为hIgHsEcUrItY,SNMP查询才被允许。
maxconn
maxconn ACL指来自客户IP地址的大量同时连接。某些squid管理员发现这是个有用的方法,用以阻止用户滥用代理或者消耗过多资源。
arp
arp ACL用于检测cache客户端的MAC地址(以太网卡的物理地址)。该特性使用非移植性代码。运行./configure时增加--enable-arp-acl选项,就可以激活该功能。
arp ACL有另一个重要限制。客户主机和squid在同一子网,它才能工作。在squid和你的用户之间有路由器存在,你可能不能使用arp ACL。
srcdom_regex
srcdom_regex ACL允许你使用正则表达式匹配客户域名。限制是:某些客户地址不能反向解析到域名。
dstdom_regex
dstdom_regex ACL也与dstdomain相似。下面的例子匹配以www开头的主机名:acl WebSite dstdom_regex -i ^www\.如下是另一个有用的正则表达式,用以匹配在URL主机名里出现的IP地址:acl IPaddr dstdom_regex [0-9]$
url_regex
url_regex ACL用于匹配请求URL的任何部分,包括传输协议和原始服务器主机名。例如,如下ACL匹配从FTP服务器的MP3文件请求:
acl FTPMP3 url_regex -i ^ftp://.*\.mp3$urlpath_regex
urlpath_regex与url_regex非常相似,不过传输协议和主机名不包含在匹配条件里。这让某些类型的检测非常容易。例如,假设你必须拒绝URL里的"sex",但仍允许在主机名里含有"sex"的请求,那么这样做:
acl Sex urlpath_regex sexbrowser
browser ACL对user-agent头执行正则表达式匹配。例如,拒绝不是来自Mozilla浏览器的请求,可以这样写:
acl Mozilla browser Mozilla http_access deny !Mozillareq_mime_type
req_mime_type ACL指客户HTTP请求里的Content-Type头部。该类型头部通常仅仅出现在请求消息主体里。req_mime_type ACL值是正则表达式。你可以这样编写ACL去捕获音频文件类型:acl AuidoFileUploads req_mime_type -i ^audio/
rep_mime_type
该类型ACL指原始服务器的HTTP响应里的Content-Type头部。它仅在使用http_reply_access规则时才有用。假如你想使用squid阻塞Java代码,你可以这样写:
acl JavaDownload rep_mime_type application/x-java http_reply_access deny JavaDownloadident_regex
ident_regex允许你使用正则表达式,代替严格的字符串匹配,这些匹配是对ident协议返回的用户名进行。例如,如下ACL匹配包含数字的用户名:acl NumberInName ident_regex [0-9]
proxy_auth_regex
该ACL允许对代理认证用户名使用正则表达式。例如,如下ACL匹配admin,administrator和administrators:
acl Admins proxy_auth_regex -i ^admin
外部ACL
外部ACL:可以指示squid发送某些信息片断到外部进程,然后外部的辅助程序告诉squid,数据匹配或不匹配。
external_acl_type指令定义新的外部ACL类型。通用语法:
external_acl_type type-name [options] format helper-commandtype-name是用户定义的字串。
Squid当前支持如下选项(options):
ttl=n:用以缓存匹配值的时间长短。 negative_ttl=n:用以缓存不匹配值的时间长短。 concurrency=n:衍生的辅助程序的数量。 cache=n:缓存结果的最大数量。 格式是以%字符开始的一个或多个关键字。squid当前支持如下格式: %LOGIN:从代理验证信用选项里获取的用户名。 %IDENT:从RFC 1413 ident获取的用户名。 %SRC:客户端IP地址。 %DST:原始服务器IP地址。 %PROTO:传输协议(例如HTTP,FTP等) %PORT:原始服务器的TCP端口。 %METHOD:HTTP请求方法。 %{Header}:HTTP请求头部的值; %{Hdr:member}:选择某些数量的基于列表的HTTP头部可以在这里包含命令参数。例如,整条命令可能类似如此:
/usr/local/squid/libexec/my-acl-prog.pl -X -5 /usr/local/squid/etc/datafile将这些放在一个长行里。squid不支持如下通过反斜杠分隔长行的技术,所以请记住所有这些必须放在单行里
编写引用它的acl行。这相对容易,语法如下:
acl acl-name external type-name [args ...]如下是个简单示例:
acl MyAcl external MyAclTypesquid接受在type-name后面的任意数量的参数。
处理长ACL列表
从外部文件里包含ACL列表。语法:acl name "filename"
这里的双引号指示squid打开filename,并且将它里面的内容分配给ACL。文件可以包含以#开头的注释。注意在该文件里的每个IP地址必须是一个单独的行。acl行里的任何地方,以空格来分隔值,新行是包含ACL值的文件的分界。
Squid如何匹配访问控制元素
squid在检查ACL元素值时使用OR逻辑。当squid找到第一个值匹配时,它停止搜索。这意味着把最可能匹配的值放在列表开头处,能减少延时。
访问控制规则
squid有大量其他的访问控制列表:
http_access:它决定哪些客户HTTP请求被允许,和哪些被拒绝。
http_reply_access:基于响应内容类型来允许或拒绝请求。 icp_access:squid被配置来服务ICP响应,那么该使用icp_access列表。 no_cache:使用no_cache访问列表来指示squid,它不必存储某些响应(在磁盘或内存里)。 miss_access:主要用于squid的邻居cache。它决定squid怎样处理cache丢失的请求。如果squid使用集群技术,那么该功能必需。 redirector_access:该访问列表决定哪个请求被发送到重定向进程。可以使用redirector_access列表来阻止某些请求被重写。 ident_lookup_access: ident_lookup_access列表与redirector_access类似。它允许你对某些请求执行懒惰ident查询。 always_direct: 该访问列表影响squid怎样处理与邻居cache转发cache丢失。never_direct: never_direct与always_direct相反。匹配该列表的cache丢失请求必须发送到邻居cache。 snmp_access: 该访问列表应用到发送给squid的SNMP端口的查询。 broken_posts: 该访问列表影响squid处理某些POST请求的方法。 cache_peer_access: 该访问列表控制发送到邻居cache的HTTP请求和ICP/HTCP查询。 reply_body_max_size: 该访问列表限制对HTTP响应主体的最大可接受size。 delay_access: 该访问规则列表控制是否延时池被应用到某个请求的cache丢失响应。 tcp_outgoing_address: 该访问列表绑定服务端TCP连接到指定的本地IP地址。 tcp_outgoing_tos: 该访问列表能设置到原始服务器和邻居cache的TCP连接的不同TOS/Diffserv值。 header_access: 使用该指令,你能配置squid从它转发的请求里删除某些HTTP头部。 header_replace: 该指令允许你替换,而不是删除,HTTP头部的内容。
访问规则语法
访问控制规则的语法如下:
access_list allow|deny [!]ACLname ...将最常用的ACL放在列表的开始位置,可以减少squid的CPU负载。
请谨慎的编写always_direct,never_direct,和no_cache规则。在always_direct中,allow规则意味着匹配的请求直接转发到原始服务器。always_direct deny规则意味着匹配的请求不强迫发送到原始服务器,但假如邻居cache不可到达,那可能还是会这么做。no_cache规则也有点麻烦。这里,你必须对不必被cache的请求使用deny。
如何匹配访问规则
squid在搜索ACL元素时使用的“或”逻辑。访问规则恰好相反,squid使用“与”逻辑。如下示例:
access_list allow ACL1 ACL2 ACL3对该匹配规则来说,请求必须匹配ACL1,ACL2,ACL3中的任何一个。
对某个规则来说,将最少匹配的ACL放在首位,能使效率最佳。考虑如下示例:
假如最后的规则是deny规则,默认动作是允许请求。在访问列表的最后加上一条,明确允许或拒绝所有请求,是好的实际做法。src 0/0 ACL表示匹配每一个和任意类型的请求。
访问列表风格
该将更具体的和受限制的访问列表放在首位。无论何时,你编写了一个带两个或更多ACL元素的规则,建议你在其后紧跟一条相反的,更广泛的规则。
延时检查
当squid遇到某个ACL不能被检查时,它延迟决定并且发布对必要信息的查询(IP地址,域名,用户名等)。当信息可用时,squid再次在列表的开头位置检查这些规则。它不会从前次检查剩下的位置继续。假如可能,你应该将这些最可能被延时的ACL放在规则的顶部,以避免不必要的,重复的检查。
减缓和加速规则检查
下列访问规则被快速检查:
header_accessreply_body_max_sizereply_accessident_lookupdelay_accessmiss_accessbroken_postsicp_accesscache_peer_accessredirector_accesssnmp_access
refresh_pattern的作用:
用于确定一个页面进入cache后,它在cache中停留的时间。
refresh_pattern规则仅仅应用到没有明确过时期限的响应。
原始服务器能使用Expires头部,或者Cache-Control:max-age指令来指定过时期限。
语法:
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是响应年龄与源年龄的比率。
常用的几个参数的意思
override-expire
该选项导致squid在检查Expires头部之前,先检查min值。这样,一个非零的min时间让squid返回一个未确认的cache命中,即使该响应准备过期。
override-lastmod
改选项导致squid在检查LM-factor百分比之前先检查min值。
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
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) * 百分比,一直到被重新确认。
squid日志TCP命中率字段解释
#cat access.log|gawk ‘{print $4}’|sort|uniq -c|sort -nr
9568 TCP_IMS_HIT/304
6313 TCP_HIT/200
2133 TCP_MISS/200
1568 TCP_MISS/206
587 TCP_MEM_HIT/200
531 TCP_MISS/304
207 TCP_REFRESH_HIT/200
152 TCP_REFRESH_HIT/304
86 TCP_NEGATIVE_HIT/404
69 TCP_MISS/404
9 TCP_MISS/000
4 TCP_MISS/503
1 TCP_REFRESH_MISS/000
1 TCP_DENIED/400
可以使用上面的方法,大约的分析一下命令中比。什么意思就看下面的详解.
#cat /var/log/squid/access.log |grep TCP_MEM_HIT
如果看到很多的TCP_MEM_HIT ,这表明该文件是从内存缓存读取的,squid已经起作用了!你再用浏览器打开该文件,应该是快如闪电了。。呵呵,大功告成了!还有其他类型的HIT,如TCP_HIT等等,这些是从磁盘读取的,我??得加速的意义不大,只不过缓解了apache的压力而已。
相应于HTTP请求,下列标签可能出现在access.log文件的第四个域。
TCP_HIT
Squid发现请求资源的貌似新鲜的拷贝,并将其立即发送到客户端。
TCP_MISS
Squid没有请求资源的cache拷贝。
TCP_REFERSH_HIT
Squid发现请求资源的貌似陈旧的拷贝,并发送确认请求到原始服务器。原始服务器返回304(未修改)响应,指示squid的拷贝仍旧是新鲜的。
TCP_REF_FAIL_HIT
Squid发现请求资源的貌似陈旧的拷贝,并发送确认请求到原始服务器。然而,原始服务器响应失败,或者返回的响应Squid不能理解。在此情形下,squid发送现有cache拷贝(很可能是陈旧的)到??户端。
TCP_REFRESH_MISS
Squid发现请求资源的貌似陈旧的拷贝,并发送确认请求到原始服务器。原始服务器响应新的内容,指示这个cache拷贝确实是陈旧的。
TCP_CLIENT_REFRESH_MISS
Squid发现了请求资源的拷贝,但客户端的请求包含了Cache-Control: no-cache指令。Squid转发客户端的请求到原始服务器,强迫cache确认。
TCP_IMS_HIT
客户端发送确认请求,Squid发现更近来的、貌似新鲜的请求资源的拷贝。Squid发送更新的内容到客户端,而不联系原始服务器。
TCP_SWAPFAIL_MISS
Squid发现请求资源的有效拷贝,但从磁盘装载它失败。这时squid发送请求到原始服务器,就如同这是个cache丢失一样。
TCP_NEGATIVE_HIT
在对原始服务器的请求导致HTTP错误时,Squid也会cache这个响应。在短时间内对这些资源的重复请求,导致了否命中。 negative_ttl指令控制这些错误被cache的时间数量。请注意这些错误只在内存cache,不会写往磁盘。下列HTTP状态码可能导致否定 cache(也遵循于其他约束): 204, 305, 400, 403, 404, 405, 414, 500, 501, 502, 503, 504。
TCP_MEM_HIT
Squid在内存cache里发现请求资源的有效拷贝,并将其立即发送到客户端。注意这点并非精确的呈现了所有从内存服务的响应。例如,某些cache在内存里,但要求确认的响应,会以TCP_REFRESH_HIT, TCP_REFRESH_MISS等形式记录。
TCP_DENIED
因为http_access或http_reply_access规则,客户端的请求被拒绝了。注意被http_access拒绝的请求在第9域的值是NONE/-,然而被http_reply_access拒绝的请求,在相应地方有一个有效值。
TCP_OFFLINE_HIT
当offline_mode激活时,Squid对任何cache响应返回cache命中,而不用考虑它的新鲜程度。
TCP_REDIRECT
重定向程序告诉Squid产生一个HTTP重定向到新的URI(见11.1节)。正常的,Squid不会记录这些重定向。假如要这样做,必须在编译squid前,手工定义LOG_TCP_REDIRECTS预处理指令。
NONE
无分类的结果用于特定错误,例如无效主机名。
相应于ICP查询,下列标签可能出现在access.log文件的第四域。
UDP_HIT
Squid在cache里发现请求资源的貌似新鲜的拷贝。
UDP_MISS
Squid没有在cache里发现请求资源的貌似新鲜的拷贝。假如同一目标通过HTTP请求,就可能是个cache丢失。请对比UDP_MISS_NOFETCH。
UDP_MISS_NOFETCH
跟UDP_MISS类似,不同的是这里也指示了Squid不愿去处理相应的HTTP请求。假如使用了-Y命令行选项,Squid在启动并编译其内存索引时,会返回这个标签而不是UDP_MISS。
UDP_DENIED
因为icp_access规则,ICP查询被拒绝。假如超过95% 的到某客户端的ICP响应是UDP_DENIED,并且客户端数据库激活了(见附录A),Squid在1小时内,停止发送任何ICP响应到该客户端。若这点发生,你也可在cache.log里见到一个警告。
UDP_INVALID
Squid接受到无效查询(例如截断的消息、无效协议版本、URI里的空格等)。Squid发送UDP_INVALID响应到客户端。