热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

提高varnish缓存命中率

现在varnish已经正常运行了,您可以通过varnish访问到您的web应用程序。如果您的web程序在设计时候没有考虑到加速器的架构,那么您可能有必要修改您的应用程序或者varnish配置文件,来提高varnish的命中率。既然这样,您就需要一个工具用来观察您和web服务器
现在varnish已经正常运行了,您可以通过varnish访问到您的web应用程序。如果您的web程序在设计时候没有考虑到加速器的架构,那么您可能有必要修改您的应用程序或者varnish配置文件,来提高varnish的命中率。
既然这样,您就需要一个工具用来观察您和web服务器之间HTTP头信息。服务器端您可以轻松的使用varnish的工具,比如varnishlog和varnishtop,但是客户端的工具需要您自己去准备,下面是我经常使用的工具。
Varnistop
您可以使用varnishtop确定哪些URL经常命中后端。Varnishtop -i txurl 就是一个基本的命令。您可以通过阅读“Statistics”了解其他示例。
Varnishlog
当您需要鉴定哪个URL被频繁的发送到后端服务器,您可以通过varnishlog对请求做一个全面的分析。varnishlog -c -o /foo/bar 这个命令将告诉您所有(-o)包含”/football/bar”字段来自客户端(-c)的请求。
Lwp-request
Lwp-request是www库的一部分,使用perl语言编写。它是一个真正的基本程序,它可以执行HTTP请求,并给您返回结果。我主要使用两个程序,GET和HEAD。
Vg.no是第一个使用varnish的站点,他们使用varnish相当完整,所以我们来看看他们的HTTP 头文件。我们使用GET请求他们的主页:
$ GET -H 'Host: www.vg.no' -Used http://vg.no/
GET http://vg.no/
Host: www.vg.no
User-Agent: lwp-request/5.834 libwww-perl/5.834
200 OK
Cache-Control: must-revalidate
Refresh: 600
Title: VG Nett - Forsiden - VG Nett
X-Age: 463
X-Cache: HIT
X-Rick-Would-Never: Let you down
X-VG-Jobb: http://www.finn.no/finn/job/fulltime/result?keyword=vg+multimedia Merk:HeaderNinja
X-VG-Korken: http://www.youtube.com/watch?v=Fcj8CnD5188
X-VG-WebCache: joanie
X-VG-WebServer: leon
OK,我们来分析它做了什么。GET 通过发送HTTP 0.9的请求,它没有主机头,所以我需要添加一个主机头使用-H选项,-U打印请求的头,-s打印返回状态,-e 答应返回状态的头,-d 丢弃当前的连接。我们正真关心的不是连接,而是头文件。
如您所见VG的头文件中有相当多的信息,比如 X-RICK-WOULD-NEVER是vg.no定制的信息,他们有几分奇怪的幽默感。其他的内容,比如X-VG-WEBCACHE 是用来调试错误的。
核对一个站点是否使用COOKIEs,可以使用下面的命令:
GET -Used http://example.com/ |grep ^Set-COOKIE
Live HTTP Headers
这是一个firefox的插件,live HTTP headers 可以查看您发送的和接收的http头。软件在https://addons.mozilla.org/en-US/firefox/addon/3829/下载。或者google“Live HTTP headers”。
The Role of HTTP headers
Varnish认为自己是真正的web服务器,因为它属于您控制。IETF没有真正定义surrogate origin cache 角色的含义,(The role of surrogate origin cache is not really well defined by the IETF so RFC 2616 doesn’t always tell us what we should do.不知如何翻译)
Cache-Control
Cache-control指示缓存如何处理内容,varnish关心max-age参数,并使用这个参数计算每个对象的TTL值。
“cache-control:nocache” 这个参数已经被忽略,不过您可以很容易的使它生效。
在头信息中控制cache-control的max-age,您可以参照下面,varnish软件管理服务器的例子:
$ GET -Used http://www.varnish-software.com/|grep ^Cache-Control
Cache-Control: public, max-age=600
Age
Varnish添加了一个age头信息,用来指示对象已经被保存在varnish中多长时间了。您可以在varnish中找到Age信息:
varnishlog -i TxHeader -I ^Age
Overriding the time-to-live(ttl)
有时候后端服务器会当掉,也许是您的配置问题,很容易修复。不过更简单的方法是修改您的ttl,能在某种程度上修复难处理的后端。
您需要在VCL中使用beresp.ttl定义您需要修改的对象的TTL:
sub vcl_fetch {
if (req.url ~ "^/legacy_broken_cms/") {
set beresp.ttl = 5d;
}
}
COOKIEs
现在Varnish接收到后端服务器返回的头信息中有Set-COOKIE信息的话,将不缓存。所以当客户端发送一个COOKIE头的话,varnish将直接忽略缓存,发送到后端服务器。
这样的话有点过度的保守,很多站点使用Google Analytics(GA)来分析他们的流量。GA设置一个COOKIE跟踪您,这个COOKIE是客户端上的一个java 脚本,因此他们对服务器不感兴趣。
对于一个web站点来说,忽略一般COOKIEs是有道理的,除非您是访问一些关键部分。这个VCL的vcl_recv片段将忽略COOKIEs,除非您正在访问/admin/:
if ( !( req.url ~ ^/admin/) ) {
unset http.COOKIE;
}
很简单,不管您需要做多么复杂的事情,比如您要删除一个COOKIEs,这个事情很困难,varnish也没有相应的工具来处理,但是我们可以使用正则表达式来完成这个工作,如果您熟悉正则表达式,您将明白接下来的工作,如果您不会我建议您找找相关资料学习一下。
我们来看看varnish软件是怎么工作的,我们使用一些GA和一些相似的工具产生COOKIEs。所有的COOKIEs使用jsp语言。Varnish和企业网站不需要这些COOKIEs,而varnish会因为这些COOKIEs而降低命中率,我们将放弃这些多余的COOKIEs,使用VCL。
下面的VCL将会丢弃所有被匹配的COOKIEs。
// Remove has_js and Google Analytics __* COOKIEs.
set req.http.COOKIE = regsuball(req.http.COOKIE, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");
// Remove a ";" prefix, if present.
set req.http.COOKIE = regsuball(req.http.COOKIE, "^;\s*", "");
下面的例子将删除所有名字叫COOKIE1和COOKIE2的COOKIEs:
sub vcl_recv {
if (req.http.COOKIE) {
set req.http.COOKIE = ";" req.http.COOKIE;
set req.http.COOKIE = regsuball(req.http.COOKIE, "; +", ";");
set req.http.COOKIE = regsuball(req.http.COOKIE, ";(COOKIE1|COOKIE2)=", "; \1=");
set req.http.COOKIE = regsuball(req.http.COOKIE, ";[^ ][^;]*", "");
set req.http.COOKIE = regsuball(req.http.COOKIE, "^[; ]+|[; ]+$", "");
if (req.http.COOKIE == "") {
remove req.http.COOKIE;
}
}
这个例子是来自varnish wiki的。
Vary
各式各样的头被发送到web server,他们让HTTP目标多样化。Accept-Encoding头就有这种感觉,当一个服务器分发一个“Vary:Accept-Encoding”给 varnish。Varnish需要cache来自客户端的每个不同的Accept-Encoding。如果客户端只接收gzip编码,varnish不对其他编码服务,那么就可以缩减编码量。
问题就是这样的,Accept-Encoding字段包含很多编码方式,下面是不同浏览器发送的:
Accept-Encodign: gzip,deflate
另一个浏览器发送的:
Accept-Encoding:: deflate, gzip
Varnish可以使两个不同的accept-enconding头标准化,这样就可以尽量减少变体。下面的VCL代码可以是accept-encoding头标准化:
if (req.http.Accept-Encoding) {
if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
# No point in compressing these
remove req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
# unkown algorithm
remove req.http.Accept-Encoding;
}
}
这段代码设置客客户端发送的accept-encoding头只有gzip和default两种编码,gzip优先。
Pitfall ? Vary:User-Agent
一些应用或者一些应用服务器发送不同user-agent头信息,这让varnish为每个单独的用户保存一个单独的信息,这样的信息很多。一个版本相同的浏览器在不同的操作系统上也会产生最少10种不同的user-agent头信息。如果您想通过基于user-agent的修改,让他们标准化,您的命中率将收到严重的打击。
Pragma
http 1.0 服务器可能会发送“Pragma:nocache”。 Varnish忽略这个头,您可以轻松的使用VCL来完成这个任务:
In vcl_fetch:
if (beresp.http.Pragma ~ "nocache") {
pass;
}
Authorization
如果varnish收到一个认证请求的头,他将pass这个请求,如果您不打算对这个头做任何操作的话。
Normalizing your namespace
有些站点访问的主机名有很多,比如http://www.varnish-software.com,http://varnish-software.com,http://varnishsoftware.com 所有的地址都对应相同的一个站点。但是varnish不知道,varnish会缓存每个地址的每个页面。您可以减少这种情况,通过修改web配置文件或者通过以下VCL:
if (req.http.host ~ "^(www.)?varnish-?software.com") {
set req.http.host = "varnish-software.com";
}
Purging
增加TTL值是提高命令率的一个好方法,如果用户访问到的内容是旧的,这样就会对您的商务照成影响。
解决方法就是当有新内容提供的时候通知varnish。可以通过两种机制HTTP purging和bans。首先,我们来看一个清理的实例:
HTTP purges
HTTP purges和HTTP GET请求相似,除了这是用来purges的。事实上您可以在任何您喜欢的时间使用这个方法,但是大多数人使用它purging。Squid支持相同的机制,为了让varnish支持purging,您需要在VCL中做如下配置:
acl purge {
"localhost";
"192.168.55.0/24";
}
sub vcl_recv {
# allow PURGE from localhost and 192.168.55...
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return (lookup);
}
}
sub vcl_hit {
if (req.request == "PURGE") {
# Note that setting ttl to 0 is magical.
# the object is zapped from cache.
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
}
您可以看见,使用了新的VCL子程序,vcl_hit和vcl_miss。当您调用lookup时将在缓存中查找目标,结果只会是miss或者hit,然后对应的子程序就会被调用,如果vcl_hit的目标存储在缓存中,并且可用,我们可以修改TTL值。
所以对于vg.no 的无效首页,他们使用varnish做如下处理:
PURGE / HTTP/1.0
Host: vg.no
如果varnish想要丢弃主页,如是很多相同URL的变体在cache中,只有匹配的变体才会被清除。清除一个相同页面的gzip变体可以使用下面命令:
PURGE / HTTP/1.0
Host: vg.no
Accept-Encoding: gzip
Bans
这是另外一种清空无效内容的方法,bans。您可以认为bans是一种过滤方法,您可以禁止某些存在cache中存在的数据。您可以基于我们拥有的元数据来禁止。
Varnish内置的CLI接口就是支持bans的。禁止vg网站上的所有png目标
purge req.http.host == "vg.no" && req.http.url ~ "\.png$"
是不是很强大?
在没有被bans命中之前的cache,是能够提供服务的。一个目标只被最新的bans检查。如果您有很多长TTL的目标在缓存中,您需要知道执行很多的Bans对性能照成的影响。
您也可以在varnish中添加bans,这样做需要一点VCL:
sub vcl_recv {
if (req.request == "BAN") {
# Same ACL check as above:
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
purge("req.http.host == " req.http.host
"&& req.url == " req.url);
# Throw a synthetic page so the
# request wont go to the backend.
error 200 "Ban added"
}
}
这是一个实用varnish的VCL处理ban的方法。添加一个ban在URL上,包含它的主机部分。

推荐阅读
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 云原生应用最佳开发实践之十二原则(12factor)
    目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • PHP组合工具以及开发所需的工具
    本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ... [详细]
  • Introduction(简介)Forbeingapowerfulobject-orientedprogramminglanguage,Cisuseda ... [详细]
  • CSS|网格-行-结束属性原文:https://www.gee ... [详细]
  • Mitchell Baker:担任 Mozilla CEO 是我最艰难的职业
    作者|MitchellBaker责编|弯月出品|CSDN(ID:CSDNnews)如果想改变互联网,我们就不能故步自封。我加 ... [详细]
  • Imdevelopinganappwhichneedstogetmusicfilebystreamingforplayinglive.我正在开发一个应用程序,需要通过流 ... [详细]
  • MySQL5.6.40在CentOS764下安装过程 ... [详细]
  • 1、概述首先和大家一起回顾一下Java消息服务,在我之前的博客《Java消息队列-JMS概述》中,我为大家分析了:然后在另一篇博客《Java消息队列-ActiveMq实战》中 ... [详细]
author-avatar
mobiledu2502890161
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有