好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

varnish3.0入门教程

第一部分:部署篇

作为一个Server Service,部署是最基本的,同时也没有太多需要说明的。按照官方的教程,一运行便可了。但是需要注意的是,–perfix什么的,具体怎么设置的,可要好好的记住,否则,以后要查起来,可就没有头绪了。另外,装了什么样的插件也要清楚的。

下面介绍下,安装方法。

针对CentOS系统,有两种方法安装,一种是通过rpm,另一种是通过源码安装。

一、通过rpm安装:

使用varnish-cache.org库,运行

rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release-3.0-1.noarch.rpm

然后运行,

yum install varnish

–no-signature只在初始安装时需要,因为Varnish的GPG key还不再yum的keyring中。

二、通过源码编译安装:

1、获得源码文件

从http://repo.varnish-cache.org/source上下载tar包,找release版的。

或者你可以通过git克隆一个。Git clone git://git.varnish-cache.org/varnish-cache

要注意通过git签出的版本会比一般情况需要更多依赖包,尤其是Python Docutils和Sphinx。

2、所需要的依赖包

automake
autoconf
libtool
ncurses-devel
libxslt
groff
pcre-devel
pkgconfig

3、配置和编译

确保上面的依赖包都满足,这样才能配置。基本命令如下

cd varnish-cache
sh autogen.sh
sh configure
make

第二部分:应用篇

当我们部署好之后,自然就是要学习怎么使用,Linux下,尤其是Server的Linux怎么可能有GUI呢。所以,学习配置文件的语法和控制台就很关键了。

下面是要的学习内容目录,我们还是依次进行。

Backend servers
Starting Varnish
Logging in Varnish
Sizing your cache
Put Varnish on port 80
Varnish Configuration Language – VCL
Statistics
Achieving a high hitrate
Cookies
Vary
Pitfall – Vary: User-Agent
Purging and banning
Edge Side Includes
Running inside a virtual machine (VM)
Advanced Backend configuration
Directors
Health checks
Misbehaving servers
Advanced topics
Troubleshooting Varnish

一、Backend servers

Varnish有后端(或称为源)服务器的概念。后端服务器是指Varnish提供加速服务的那台,通常提供内容。

第一件要做的事情是告诉Varnish,哪里能找到要加速的内容。打开varnish配置文件,源码包安装的在/usr/local/etc/varnish/default.vcl中,rpm安装的在/etc/varnish/default.vcl中。

顶部有如下注释:

# backend default {
# .host = "127.0.0.1";
# .port = "8080";
# }
backend default {
.host = "127.0.0.1";
.port = "80";
}

三、Logging in Varnish

在Varnish中,日志的工作方式,是一个很好特性。Varnish将日志记录到共享内存片段,而不是记录到一个普通文件中。当记录到内存片段的最后处,会再从头开始记,覆写老数据。这个比记录到文件要快的多,而且不需要磁盘空间。

另一方面,如果你没有执行程序去将这些日志写到磁盘中的话,他们是会消失的。

Varnishlog是一个用来查看Varnish日志的程序。Varnishlog提供给我们原始日志。这里还有其他客户端,之后我们会介绍。

在启动varnish的终端窗口,我们输入varnishlog,然后按回车。

你会看到如下内容,使用”.”可以缓缓滚动:

0 CLI - Rd ping
0 CLI - Wr 200 PONG 1273698726 1.0

这是varnish主进程,检查缓存进程,看是否一切正常。

现在在浏览器,重新加载页面,显示你的web应用。你会看到如下内容:

11 SessionOpen c 127.0.0.1 58912 0.0.0.0:8080
11 ReqStart c 127.0.0.1 58912 595005213
11 RxRequest c GET
11 RxURL c /
11 RxProtocol c HTTP/1.1
11 RxHeader c Host: localhost:8080
11 RxHeader c Connection: keep-alive

vcl_fetch

vcl_fetch是在文档从后端被成功接收后调用的。通常用于调整响应头信息,触发ESI处理,万一请求失败就换个后端服务器。

在vcl_fecth中,你还可以使用请求对象req。还有个后端响应对象beresp。Beresp包含了后端的HTTP头信息。

actions

最常用的action如下:

pass:当返回pass的时候,请求和随后的响应都将被传到后端服务器,或从那里传回。不会被缓存。pass可以在vcl_recv中被返回。

hit_for_pass:类似与pass,但是只有vcl_fetch可以用。不像pass,hit_for_pass将在缓存中创建一个hitforpass对象。这有个副作用,就是缓存了不像缓存的东西。同时会将未缓存的请求传到后端。在vcl_recv中这样的逻辑不是必须的,因为它发生在任何潜在对象队列发生之前。

lookup:当在vcl_recv中返回lookup时,就等于你告诉varnish发送缓存中的内容,即使该请求应该是被pass的。在vcl_fetch中不能使用lookup。

pipe:pipe也可以在vcl_recv中返回。pipe缩短了客户和后端的环路链接,并且varnish将只是待在哪里,来回偏移字节。varnish不会在意来回发送的数据,所以你的日志是不完整的。注意一个客户会基于相同链接发送几个请求,当使用HTTP 1.1时。所以在实际返回pipe之前,你需要让varnish添加”Connection:close”的头信息。

deliver:投递缓存对象给客户。经常在vcl_fetch中使用。

请求,响应和对象

在VCL中,有三种重要的数据结构。请求:来自客户端;响应:来自后端服务器;对象:存储在缓存中。

在VCL中你应该知道以下结构。

req:请求对象。当varnish接受了请求,req就会创建并生产。许多在vcl_recv中要做的工作都需要用到req。

beresp:后端响应对象。包含了从后端返回的对象的头信息。vcl_fetch中,你会使用beresp对象。

obj:缓存了的对象。大多数是驻留在内存中的只读对象。obj.ttl是可以写的,剩下的都是只读的。

操作符

VCL中可用的操作符如下,稍后可以看例子:

=:赋值

==:比较

~:匹配。可使用正则表达式或ACLs

!:取反

&&:逻辑与

||:逻辑或

例1 – 操作头信息

移除所有在web服务器的/images目录中的对象的cookie:

sub vcl_recv {
if (req.url ~ "^/images") {
unset req.http.cookie;
}
}

现在,当请求传到后端服务器时,他是不带有cookie头信息的。需要在意的是if语句,它根据正则表达式匹配了URL(属于请求对象)。注意匹配操作符。如果它匹配,请求的cookie头信息就会被删除。

例2 – 操作beresp

这里如果匹配某种条件,我们就重写beresp的TTL属性

sub vcl_fetch {
if (req.url ~ "\.(png|gif|jpg)$") {
unset beresp.http.set-cookie;
set beresp.ttl = 1h;
}
}

例3 – ACLs

你创建了一个使用acl关键字的访问控制列表。你可以使用匹配操作符去判断客户端的IP地址是否与一个ACL匹配。

# Who is allowed to purge....
acl local {
"localhost";
"192.168.1.0"/24; /* and everyone on the local network */
! "192.168.1.23"; /* except for the dialin router */
}
sub vcl_recv {
if (req.request == "PURGE") {
if (client.ip ~ local) {
return(lookup);
}
}
}
sub vcl_hit {
if (req.request == "PURGE") {
set obj.ttl = 0s;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
error 404 "Not in cache.";
}
}

八、Achieving a high hitrate

现在Varnish已经运行,并且你可以通过Varnish访问你的站点。除非你的应用是专门为在一个web加速器后工作而写的,否则为了在Varnish中获得高命中率,你可能需要在配置或应用上做一些修改。

除非varnish完全确定缓存你的数据室安全,否则varnish是不会缓存的。所以,为了让你明白varnish是如何确定的,并使如何缓存页面的,我将通过一些很有用工具去引导你:

注意你需要一个工具去观察传输于你和web服务器之间的HTTP头信息。在varnish服务器上,首先是使用varnishlog和varnishtop,但有时候需要客户端工具去搞清楚。下面就是我们用到的。

工具:varnishtop

你可以使用varnishtop确定出后端命中最多的URL。varnishtop –i txurl是必须的命令。你可以在前一节Statistics中,看到一些其他的varnishtop的例子。

工具:varnishlog

当你已经确定了最常发送给后端的URL是多少时,你可以使用varnishlog去查看完整的请求。varnishlog –c –o /foo/bar将给你来自客户端(-c)的完整(-o)的匹配/foo/bar的请求。

对于扩展诊断头信息,可以参看:http://www.varnish-cache.org/trac/wiki/VCLExampleHitMissHeader

工具:lwp-request

lwp-request是perl的World-Wide Web library中的一部分。它是一些基本的程序,这些程序可以处理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通常发送HTTP0.9请求,其缺少Host头信息。所以我通过-H添加了一个Host头信息。-U打印请求头信息,-s打印响应状态,-e打印响应头信息,-d丢弃实际内容。我们并不关心内容,只要头信息。

你可以发现,VG在他们的头信息中添加了一些信息。像X-Rick-Would-Never表示了vg.no的某种奇怪的幽默。其他,像X-VG-Webcache是用来调试的。

所以,你可以检查一个站点的特定URL是否设置了cookie,只需要:

GET -Used http://example.com/ |grep ^Set-Cookie

工具:实时HTTP头信息

Firefox也有个插件。Live HTTP Headers可以显示你发送和接受到的头信息。你可以通过google找到“Live HTTP Header”,或者到https://addons.mozilla.org/en-US/firefox/addon/3829/可以找到。

HTTP头信息的角色

随着每个HTTP请求和响应变成一群携带原数据的头信息。varnish将查看这些头信息,以确定这里的内容是否适合缓存,以及缓存多久。

请注意,当考虑这些头信息时候,实际上varnish只考虑真实web服务器中varnish自己的那部分。考虑的理论依据都在于你的控制。

术语surrogate origin cache没有在IETF so RFC2616中很好的定义。所以varnish不同的工作方式可能会和你的预期不同。

让我们看看你应该知道的重要的头信息:

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中该对象被保持了多久。你可以通过varnishlog像下面那样抓出Age:

varnishlog -i TxHeader -I ^Age

Pragma

一个HTTP 1.0服务器可能会发送”Pragma:nocache”。Varnish忽略这种头信息。在VCL中你可以很方便的增加对这种头信息的支持。

在vcl_fetch中:

if (beresp.http.Pragma ~ "nocache") {
pass;
}
Authorization

如果varnish看到授权头信息时,它会pass该请求。如果这不是你希望的,你可以unset这个头信息。

Overriding the time-to-live(ttl)

有时你的后端会误操作。根据你的安装,在varnish中覆写ttl会比修复你某些麻烦的后端要简单的多。

你需要VCL去确定你想要的对象,然后你将beresp.ttl的值设置成你想设置的值。

sub vcl_fetch {
if (req.url ~ "^/legacy_broken_cms/") {
set beresp.ttl = 5d;
}
}

该例会为你网站上过去的遗留物,将TTL设置为5天。

Forcing caching for certain requests and certain responses

由于你还在使用那些麻烦的不能很好工作的后端,你可能会想再varnish中覆写更多的内容。我们推荐你尽可能多的使用默认缓存规则。尽管强制varnish在缓存中查找一个对象很简单,但我们还是不推荐。

Normalizing your namespace

一些站点可以通过很多主机名访问。比如, http://www.varnish-software.com/ , http://varnish-software.com/和http://varnishsoftware.com/。这些都指向同一个站点。由于varnish不知道他们的区别,varnish会为每个主机名的每个页面做缓存。你可以通过在你的web服务器配置中设置跳转或者使用VCL来缓解这个情况:

if (req.http.host ~ "(?i)^(www.)?varnish-?software.com") {
set req.http.host = "varnish-software.com";
}

Ways of increasing your hitrate even more

接下来的章节,会阐述进一步提高命中率的方法,尤其在cookies的章节中。

Cookies

Vary

Purging and banning

Edge Side Includes

九、Cookies

varnish不会缓存来自后端的具有Set-Cookie头信息的对象。同样,如果客户端发送了一个Cookie头信息,varnish将绕过缓存,直接发给后端。

这可能太过保守。很多站点使用Google Analytics(GA)去分析他们的流量。GA通过设置cookie去跟踪。这个cookie是供客户端的JavaScript程序使用的,服务器是不需要的。

对很多web应用,它会完全忽视cookies,除非你正在访问网站的特定部分。在vcl_recv中的下面的VCL代码块将忽略cookies,除非你访问/admin/:

if ( !( req.url ~ ^/admin/) ) {
unset req.http.Cookie;
}

非常简单。然后,如果你需要做更复杂的处理,像在几个cookie中移除其中一个,事情就麻烦了。遗憾的是,varnish没有很好的工具去操作cookie。我们不得不使用正则表达式去做这件事情。如果你熟悉正则表达式,你就明白怎么办了。如果你不熟悉,我建议你找本书好好学习下,或者通过pcrepattern手册页面或其他的在线教程。

让我展示给你看看,varnish软件是用什么的。我们使用一些GA的跟踪cookie或其他类似工具的cookie。这些cookie都是供JavaScript使用的。varnish和其联盟站不需要这些cookie,并且因为varnish会因为这些cookie不缓存页面,所以当客户端发送cookie时,我们将在VCL中丢弃这些非必要的cookie。

下面的VCL中,我们丢弃了所有的以“_”开头的cookie:

// 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 = regsub(req.http.Cookie, "^;\s*", "");
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;
}
}

十二、Purging and banning

最有效提升命中率的方法是增加你对象的ttl(time-to-live存活时间)。但是,你要知道,在微博时代,提供过时的内容是很不利于业务的。

解决方案是,当有新内容时,就通知varnish。这可以通过两个机制实现。HTTP清理(PURGE,以下称PURGE)和禁止(BAN,以下简称BAN)。首先让我们解释下HTTP PURGE

HTTP PURGE

PURGE(清理)是指当你选出一个缓存对象时,根据其变化的内容进行丢弃。通常PURGE是通过HTTP的PURGE方法进行调用的(即method=purge,这个purge是http协议中没有预定义的,应该是varnish中扩展的)。

HTTP PURGE类似于HTTP GET请求,只是method是PURGE。事实上,你可以调用任何你希望的method,不过许多人都倾向于使用PURGE。Squid支持相同的机制。为了在varnish支持PURGE,你需要以下代码:

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") {
purge;
error 200 "Purged.";
}
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged.";
}
}

正如你看到的。我们使用了新的VCL子程序,vcl_hit和vcl_miss。当我们调用lookup时,varnish将尝试在缓存中查找对象。要么命中,要么丢失,然后调用相应的子程序。在vcl_hit中,我们可以获得存于缓存中的对象,并且可以设置它的TTL。

所以,对于example.com,要让它的首页失效(表示要拿新的内容),可以这样请求varnish:

PURGE / HTTP/1.0
Host: example.com

之后,Varnish就会丢弃主页。这会移除所有变量,如vary所定义的。

Ban

这是另一个让内容失效的方法。禁止(BAN),你可以将其认为是一种过滤器。你禁止你的缓存提供某些内容。你可以根据我们有的元数据,进行禁止。

Varnish支持禁止功能,并且可以再CLI接口中获得。对于VG,如果想禁止属于example.com的png对象,他们可以分发以下内容:

ban req.http.host == "example.com" && req.http.url ~ "\.png$"

真的很强大。

当在缓存中命中对象时且在投递之前,就会检查其是否BAN。一个对象只会被较新的BAN检查。

只对beresp.*起作用的BAN,由背景工作线程运行着,称为ban lurker。ban lurker将检查堆,看看是否匹配对象,并且去除匹配对象。ban lurker的频度(活跃度),可以通过ban_lurker_sleep参数控制。

禁止那些较老的,对于缓存中最老的对象不经验证就直接丢弃。如果你有很多具有长TTL对象,这些对象很少被访问,那么你会累积大量的禁止。这会影响CPU的利用率和性能。

你可以通过HTTP向varnish添加BAN。这样做需要一些VCL:

sub vcl_recv {
if (req.request == "BAN") {
# Same ACL check as above:
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
ban("req.http.host == " + req.http.host +
"&& req.url == " + req.url);
# Throw a synthetic page so the
# request won't go to the backend.
error 200 "Ban added";
}
}

十三、Edge Side Includes

Edge Side Includes(边界情况包含)是一种语言,用来包含在其他web页面中的web页面片断。可以认为他是一个通过HTTP实现的HTML包含语句。

在许多web站点,许多内容是各页面间共享的。为每个页面重新生成这些内容是很浪费的,并且ESI(Edge Side Includes的缩写)致力于让你为每个片断单独决定缓存策略。

在varnish中,我们只实现了ESI的一个小的子集。自2.1起,我们就有三个ESI语句:

esi:include

esi:remove

<!–esi …–>

基于变量和cookie的内容替换还没有实现,但是已经在计划中了。

例子:esi include

让我们看看如何使用它。这段简单的cgi脚本,输出了日期:

#!/bin/sh
echo 'Content-type: text/html'
echo ''
date "+%Y-%m-%d %H:%M"
<HTML>
<BODY>
The time is: <esi:include src="/cgi-bin/date.cgi"/>
at this very moment.
</BODY>
</HTML>
sub vcl_fetch {
if (req.url == "/test.html") {
set beresp.do_esi = true; /* Do ESI processing */
set beresp.ttl = 24 h; /* Sets the TTL on the HTML above */
} elseif (req.url == "/cgi-bin/date.cgi") {
set beresp.ttl = 1m; /* Sets a one minute TTL on */
/* the included object */
}
}
<esi:include src="http://www.example.com/ad.html"/>
<esi:remove>
<a href="http://www.example.com">www.example.com</a>
</esi:remove>

例子:<!—esi…–>

这是一个特殊的构造,允许ESI标记的HTML呈现,而无需处理。当处理页面时,ESI处理器将移除开始(<–esi)和结尾(–>),然而仍然会处理其内容。如果页面没有被处理,它将会留下,编程HTML/XML的注释标签。例如:

<!--esi
<p>Warning: ESI Disabled!</p>
</p> -->

十五、Advanced Backend Configuration

某些情况,你可能需要让varnish缓存几个服务器的内容。你可能希望varnish映射所有URL到一个或多个主机。这里有许多选项。

比如,我们需要引入一个Java应用到PHP网站。我们的Java应用会处理以/java/开头的URL。

我们将东西起起来,运行在8000端口。现在来看看default.vcl:

backend default {
.host = "127.0.0.1";
.port = "8080";
}

我们添加新的后端:

backend java {
.host = "127.0.0.1";
.port = "8000";
}

现在我们要指示,发送不同URL的规则。看看vcl_recv:

sub vcl_recv {
if (req.url ~ "^/java/") {
set req.backend = java;
} else {
set req.backend = default.
}
}

非常简单。现在先让我们停一下,考虑一下这里的情况。如你所见,你可以根据任意情况定义如何选择后端。如果你发送移动设备的请求到不同的后端,可以做类似的操作,if(req.User-agent ~ /mobile/)

十六、Directors

Director(不知道怎么翻译合适,所以就保留了)

你也可以将几个后端分组为一组后端。这些组称为directors。这可以提高性能和灵活度。你可以定义几个后端,并把它们归到一个director中

backend server1 {
.host = "192.168.0.10";
}
backend server2{
.host = "192.168.0.10";
}

现在创建一个director:

director example_director round-robin {
{
.backend = server1;
}
# server2
{
.backend = server2;
}
# foo
}

十七、Health checks

让我们建立一个director,该director具有两个后端并带健康检查。首先让我们定义后端:

backend server1 {
.host = "server1.example.com";
.probe = {
.url = "/";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;
}
}
backend server2 {
.host = "server2.example.com";
.probe = {
.url = "/";
.interval = 5s;
.timeout = 1 s;
.window = 5;
.threshold = 3;
}
}

probe是新的内容。varnish将使用probe对每个后端进行健康检查。其选项有:

url:定义什么样的URL需要varnish(感觉这里应该是做处理的意思)请求。

interval:查询的间隔时长

timeout:probe的超时时间

window:varnish将保持一个结果的滑动窗(该滑动窗不是实际的窗体,是一种流量控制方法,允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。)。这里窗口有5个确认点。

threshold:上次查询的.window数量为多少时,就代表后端是健康的。

initial:当varnish启动时候,用多少个probe去探测健康情况——默认情况,此数量与threshold的数量一致。

现在我们定义director:

director example_director round-robin {
{
.backend = server1;
}
# server2
{
.backend = server2;
}
}

十八、Misbehaving servers

varnish有个重要的特性,它可以保护你免受web-和应用服务器的不良行为。

Grace mode

当几个客户端正访问相同页面时,varnish会发送一个请求到后端,并且让其他请求等待,当从后端取回一个副本时。在某些产品中,这称为请求黑那个,varnish会自动做这个。

如果你每秒需要相应成千上万的点击,等待的请求队列就会很巨大。这里有两个潜在问题,一个是thundering herd problem(这个无法翻译。。。wiki有专门的对应解释),突然增加一千个线程去提供内容,会让负载变得很高。第二个,没有人喜欢等。为了解决这个问题,我们指示varnish去保持缓存的对象超过他们的TTL(就是该过期的,不让它过期),并且去提供旧的内容给正在等待的请求。

所以,为了提供旧的内容,首先我们必须有内容去提供。所以,我们使用以下VCL,以使varnish保持所有对象超出了他们的TTL30分钟。

sub vcl_fetch {
set beresp.grace = 30m;
}

这样,varnish还不会提供旧对象。为了启用varnish去提供旧对象,我们必须在请求上开启它。下面表示,我们接收15s的旧对象:

sub vcl_recv {
set req.grace = 15s;
}

你可能想知道,为什么,如果我们无法提供这些对象,我们在缓存中保持这些对象30分钟?如果你开启健康检查,你可以检查后端是否出问题。如果出问题了,我们可以提供长点时间的旧内容。

if (! req.backend.healthy) {
set req.grace = 5m;
} else {
set req.grace = 15s;
}

所以,总结下,优雅模式解决了两个问题:

1、 通过提供旧的内容,避免请求扎堆。

2、 如果后端坏了,提供旧的内容。

Saint mode

有时候,服务器会比较奇怪。他们开始抛出随机错误。你可以指示varnish去处 理这些错误,用一种更加优雅得方式——神圣模式。神圣模式可以让你抛弃一个后端服务器的某个页面,并尝试从其他服务器获取,或提供缓存中的旧内容。让我们看看如何在VCL中开启:

sub vcl_fetch {
if (beresp.status == 500) {
set beresp.saintmode = 10s;
restart;
}
set beresp.grace = 5m;
}

十九、Advanced topics

该教程涉及了varnish中的基础。如果你通读了它,你现在应该已经有运行varnish的能力了。这里是一个简短的我们在本教程中没有谈到的专题概览。

更多VCL

VCL比至少我们所说的要复杂一点。这里有一些更多我们没有谈到的子程序和action可用。要查看VCL的完整教程,可以参看VCL的手册页面——reference-vcl

使用内嵌C扩展varnish

你可以使用内嵌C去扩展varnish。注意,这种方式可能会把varnish搞乱。因为C语言在varnish缓存处理中运行,所以如果你的代码出现一点错误,varnish就会崩溃。

我看到的第一个内嵌C应用是写入syslog:

# The include statements must be outside the subroutines.
C{
#include <syslog.h>
}C
sub vcl_something {
C{
syslog(LOG_INFO, "Something happened at VCL line XX.");
}C
}
Edge Side Includes

varnish可以通过把不同页面放到一起,缓存、创建web页面。这些片断可以有自己的缓存策略。如果你的网站有一个显示最热的5篇文章的列表,该列表可能被作为片断缓存起来,并且被包含在其他页面中。使用属性可以很好地提升命中率并降低服务器负载。ESI看上去是这样的:

<HTML>
<BODY>
The time is: <esi:include src="/cgi-bin/date.cgi"/>
at this very moment.
</BODY>
</HTML>
sub vcl_fetch {
if (req.url == "/test.html") {
set beresp.do_esi = true; /* Do ESI processing */
}
}
storage_malloc: max size 1024 MB.
Using old SHMFILE
Platform: Linux,2.6.32-21-generic,i686,-smalloc,-hcritbit
200 193
-----------------------------
Varnish Cache CLI.
-----------------------------
Type 'help' for command list.
Type 'quit' to close CLI session.
Type 'start' to launch worker process.

现在varnish已经启动。只有主进程运行着,在调试模式下,缓存是不会运行的。现在你正处于控制台。你可以通过分发“start”,指示主进程开始缓存。

start
bind(): Address already in use
300 22
Could not open sockets

这里我们发现个问题。有些其他什么绑定在了varnish的HTTP端口上了。如果这没有什么帮助,就在IRC上尝试下trace、truss或come find us。

Varnish崩溃

当varnish损坏,子进程就会崩溃。常常母进程将通过再次重启子进程去解决。任何错误都会被记录在syslog中。看上去会像以下:

Mar 8 13:23:38 smoke varnishd[15670]: Child (15671) not responding to CLI, killing it.
Mar 8 13:23:43 smoke varnishd[15670]: last message repeated 2 times
Mar 8 13:23:43 smoke varnishd[15670]: Child (15671) died signal=3
Mar 8 13:23:43 smoke varnishd[15670]: Child cleanup complete
Mar 8 13:23:43 smoke varnishd[15670]: child (15697) Started

查看更多关于varnish3.0入门教程的详细内容...

  阅读:50次