国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Varnish3.0中文入門教程 | AnyKoro

Varnish3.0中文入門教程

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

然后運(yùn)行,

1
yum install varnish

–no-signature只在初始安裝時(shí)需要,因?yàn)閂arnish的GPG key還不再yum的keyring中。
二、通過(guò)源碼編譯安裝:
1、獲得源碼文件
http://repo.varnish-cache.org/source上下載tar包,找release版的。
或者你可以通過(guò)git克隆一個(gè)。Git clone git://git.varnish-cache.org/varnish-cache
要注意通過(guò)git簽出的版本會(huì)比一般情況需要更多依賴包,尤其是Python Docutils和Sphinx。
2、所需要的依賴包

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

3、配置和編譯
確保上面的依賴包都滿足,這樣才能配置?;久钊缦?/p>

1
2
3
cd varnish-cache
sh autogen.sh
sh configure

make

通常configure腳本接收多個(gè)參數(shù),現(xiàn)在你可以不用管它,Varnish中幾乎所有的一切都是運(yùn)行時(shí)參數(shù)。
在你安裝之前,你可能希望運(yùn)行回歸測(cè)試(再次驗(yàn)證程序正確與否的測(cè)試),這會(huì)消耗一些時(shí)間,喝杯咖啡去吧:

make check

別因?yàn)橐粌蓚€(gè)測(cè)試失敗而擔(dān)心,有些測(cè)試對(duì)時(shí)間太敏感(請(qǐng)告訴我們是哪些,我們可以修復(fù)它),如果出現(xiàn)大量失敗情況,尤其是b00000.vtc測(cè)試失敗時(shí),那就不能怠慢了,只有解決它才行。
4、安裝
最后,通過(guò)測(cè)試后:

1
make install

Varnish將安裝在/usr/local。Varnishd二進(jìn)制文件在/usr/local/sbin/varnishd中,默認(rèn)的配置文件在/usr/local/etc/varnish/default.vcl


第二部分:應(yīng)用篇
當(dāng)我們部署好之后,自然就是要學(xué)習(xí)怎么使用,Linux下,尤其是Server的Linux怎么可能有GUI呢。所以,學(xué)習(xí)配置文件的語(yǔ)法和控制臺(tái)就很關(guān)鍵了。
下面是要的學(xué)習(xí)內(nèi)容目錄,我們還是依次進(jìn)行。

  1. Backend servers
  2. Starting Varnish
  3. Logging in Varnish
  4. Sizing your cache
  5. Put Varnish on port 80
  6. Varnish Configuration Language – VCL
  7. Statistics
  8. Achieving a high hitrate
  9. Cookies
  10. Vary
  11. Pitfall – Vary: User-Agent
  12. Purging and banning
  13. Edge Side Includes
  14. Running inside a virtual machine (VM)
  15. Advanced Backend configuration
  16. Directors
  17. Health checks
  18. Misbehaving servers
  19. Advanced topics
  20. Troubleshooting Varnish

一、Backend servers
Varnish有后端(或稱為源)服務(wù)器的概念。后端服務(wù)器是指Varnish提供加速服務(wù)的那臺(tái),通常提供內(nèi)容。
第一件要做的事情是告訴Varnish,哪里能找到要加速的內(nèi)容。打開(kāi)varnish配置文件,源碼包安裝的在/usr/local/etc/varnish/default.vcl中,rpm安裝的在/etc/varnish/default.vcl中。
頂部有如下注釋:

1
2
3
4
# backend default {
# .host = "127.0.0.1";
# .port = "8080";
# }

我們修改下,把8080變成80

1
2
3
4
backend default {
.host = "127.0.0.1";
.port = "80";
}

這段配置,定義了一個(gè)Varnish中的一個(gè)后端(Backend),叫做default。當(dāng)Varnish需要從這個(gè)后端獲得內(nèi)容時(shí),它就會(huì)連接到127.0.0.1的80端口上。
Varnish可以有多個(gè)后端,你甚至可以為了負(fù)載均衡將幾個(gè)后端加入到一個(gè)集群后端中。
現(xiàn)在我們完成了Varnish的基本配置,接下來(lái)讓我們?cè)?080端口上把Varnish起起來(lái),對(duì)它做些實(shí)驗(yàn)性測(cè)試。

二、Starting Varnish
在開(kāi)始下面的內(nèi)容之前,你先要確?,F(xiàn)在你的varnish沒(méi)有在運(yùn)行,如果有,就用pkill varnishd去關(guān)閉它。然后到根目錄,輸入以下代碼:

1
# varnishd –f /usr/local/etc/varnish/default.vcl –s malloc,1G -T 127.0.0.1:2000 –a 0.0.0.0:8080

我添加了一些選項(xiàng):
-f /urs/local/etc/varnish/default.vcl
-f選項(xiàng)指定了將使用哪個(gè)配置文件
-s malloc,1G
-s選項(xiàng)用于指定varnish使用何種存儲(chǔ)類型保存內(nèi)容。這里我使用malloc,這個(gè)代表我只使用內(nèi)存存儲(chǔ)。如果還有其他后端,用:ref:tutorial-storage來(lái)表示。1G指定了分配多少內(nèi)存——這里是一個(gè)G。
-T 127.0.0.1:2000
Varnish含有內(nèi)置文本管理界面??梢酝ㄟ^(guò)它對(duì)varnish進(jìn)行管理,最主要你還不用停掉varnish。你可以給管理界面分配端口。確保你的管理界面沒(méi)有暴露給外界,因?yàn)橥ㄟ^(guò)Varnish管理界面你可以很容易地訪問(wèn)系統(tǒng)根目錄。我建議直接綁定在localhost上,就別遠(yuǎn)程了。如果你的系統(tǒng)上有不可信任的user,就用防火墻規(guī)則只要限制界面訪問(wèn)根目錄就行。
-a 0.0.0.0:8080
對(duì)于進(jìn)入的HTTP請(qǐng)求,我指定varnish監(jiān)聽(tīng)8080。對(duì)于生產(chǎn)環(huán)境,你可能需要讓varnish監(jiān)聽(tīng)在80端口,這個(gè)是默認(rèn)的。(關(guān)鍵看前面有沒(méi)有負(fù)載均衡)

現(xiàn)在我已經(jīng)啟動(dòng)了Varnish。用瀏覽器訪問(wèn)下http://varnishServerIP:8080/。你應(yīng)該會(huì)看到你的web應(yīng)用的運(yùn)行的。
Varnish運(yùn)行后,應(yīng)用的訪問(wèn)速度更快主要取決于一些因素。如果你的應(yīng)用為每個(gè)session使用cookie的話(很多PHP和Java應(yīng)用無(wú)論是否需要都會(huì)發(fā)送一個(gè)session cookie),或者應(yīng)用使用驗(yàn)證的話,這些varnish都不會(huì)緩存?,F(xiàn)在先放一放,別考慮這些,等到Achieving a high hitrate的時(shí)候,我們?cè)賮?lái)好好談。
通過(guò)查看日志,我們可以用來(lái)確定varnish是不是真的起作用了。

三、Logging in Varnish
在Varnish中,日志的工作方式,是一個(gè)很好特性。Varnish將日志記錄到共享內(nèi)存片段,而不是記錄到一個(gè)普通文件中。當(dāng)記錄到內(nèi)存片段的最后處,會(huì)再?gòu)念^開(kāi)始記,覆寫(xiě)老數(shù)據(jù)。這個(gè)比記錄到文件要快的多,而且不需要磁盤空間。
另一方面,如果你沒(méi)有執(zhí)行程序去將這些日志寫(xiě)到磁盤中的話,他們是會(huì)消失的。
Varnishlog是一個(gè)用來(lái)查看Varnish日志的程序。Varnishlog提供給我們?cè)既罩?。這里還有其他客戶端,之后我們會(huì)介紹。
在啟動(dòng)varnish的終端窗口,我們輸入varnishlog,然后按回車。
你會(huì)看到如下內(nèi)容,使用”.”可以緩緩滾動(dòng):

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

這是varnish主進(jìn)程,檢查緩存進(jìn)程,看是否一切正常。
現(xiàn)在在瀏覽器,重新加載頁(yè)面,顯示你的web應(yīng)用。你會(huì)看到如下內(nèi)容:

1
2
3
4
5
6
7
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

第一列可以是任意的數(shù)字,它代表具體的請(qǐng)求。數(shù)字相同,表示他們是同屬于一個(gè)HTTP事務(wù)的。第二列是日志信息的標(biāo)簽。所有的日志條目都是用一個(gè)標(biāo)簽去標(biāo)記,該標(biāo)簽代表何種行為被記錄。以Rx開(kāi)頭的標(biāo)簽代表varnish正在接受數(shù)據(jù),Tx代表正在發(fā)送數(shù)據(jù)。
第三列表示數(shù)據(jù)的是來(lái)自或者要發(fā)送給客戶(c),另外,還有為b的情況,代表數(shù)據(jù)來(lái)自或要發(fā)送給后端(b)。第四列是被記錄的數(shù)據(jù)。
現(xiàn)在,你可以使用varnishlog去過(guò)濾下?;镜倪x項(xiàng)如下:
-b 只顯示varnish和后端服務(wù)器之間通信的記錄條。當(dāng)你想優(yōu)化緩存命中率的時(shí)候,非常有用。
-c 和-b類似,只是針對(duì)與客戶端的通信情況。
-i tag 只有顯示帶有特定標(biāo)簽的行。”varnishlog –I SessionOpen”將只顯示新會(huì)話的情況。注意標(biāo)簽是大小寫(xiě)敏感的。
-I 通過(guò)正則表達(dá)式過(guò)濾數(shù)據(jù),并顯示匹配行?!?varnishlog –c –I RxHeader –I Cookie”,將顯示所有來(lái)自客戶端的cookie頭信息。
-o 根據(jù)請(qǐng)求id,將記錄條目分組。
現(xiàn)在Varnish差不多工作正常,現(xiàn)在要將Varnish的端口編程80,進(jìn)行調(diào)優(yōu)。

四、Sizing your cache
給Varnish選擇多少內(nèi)存,是個(gè)很艱巨的問(wèn)題。你需要考慮以下事情:
l 你的熱門數(shù)據(jù)集有多大。對(duì)一個(gè)門戶或者新聞?wù)緛?lái)說(shuō),這個(gè)數(shù)據(jù)集可能就只是首頁(yè)和它相關(guān)內(nèi)容的大小。這里包括的兩部分,一部分是只首頁(yè)本身的文字圖片內(nèi)容,另一部分是首頁(yè)會(huì)鏈接到的頁(yè)面或?qū)ο螅ū热鐖D片),這個(gè)很容易理解,首頁(yè)的內(nèi)容是最可能被點(diǎn)擊的,命中率也會(huì)很高。
l 產(chǎn)生一個(gè)對(duì)象的花費(fèi)有多大?有時(shí)候,如果從后端返回并不太消耗資源,同時(shí)你的內(nèi)存又有限的話,我們應(yīng)該緩存一部分圖片,而不是去緩存所有圖片。
l 使用varnishstat或其他工具監(jiān)控n_lru_nuked計(jì)數(shù)器。如果你有很多LRU活動(dòng)的話,那么你的緩存正因空間限制在清除對(duì)象,此時(shí)你就要考慮增加緩存大小了。
清楚緩存任何對(duì)象都會(huì)攜帶保存在實(shí)際存儲(chǔ)區(qū)域之外的開(kāi)銷。所以,即便你指定-s malloc,16G,varnish可能實(shí)際使用了兩倍。Varnish中每個(gè)對(duì)象的花銷大概是1k。所以,如果在你的緩存中有很多小對(duì)象的話,花銷是非常大的。

五、Put Varnish on port 80
直到現(xiàn)在,為了測(cè)試,我們都把varnish運(yùn)行在一個(gè)高位端口上。你應(yīng)該測(cè)試你的應(yīng)用,如果它工作正常,我們就要切換了,Varnish運(yùn)行在80端口上,你的web服務(wù)器運(yùn)行在高位端口上。
首先停止varnishd:

1
# pkill varnishd

并停止你的web服務(wù)器。修改web服務(wù)器的配置,將其綁定到8080端口上,替換掉原來(lái)的80?,F(xiàn)在打開(kāi)varnish的default.vcl并且改變default后端的端口到8080。
啟動(dòng)你的web服務(wù)器并且開(kāi)啟varnish:

1
# varnishd -f /usr/local/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000

注意,我們移除了-a選項(xiàng)。因?yàn)?,現(xiàn)在我們采用Varnish的默認(rèn)設(shè)置即可,它會(huì)自動(dòng)綁定到http的80端口上?,F(xiàn)在每個(gè)訪問(wèn)你站點(diǎn)的人,都會(huì)通過(guò)varnish訪問(wèn)。

六、Varnish Configuration Language – VCL
Varnish有強(qiáng)大的配置系統(tǒng)。許多其他的系統(tǒng)使用配置指令,基本上就是開(kāi)或關(guān)很多開(kāi)關(guān)。Varnish使用領(lǐng)域?qū)S谜Z(yǔ)言(DSL)作為Varnish配置語(yǔ)言,簡(jiǎn)寫(xiě)VCL。當(dāng)請(qǐng)求到達(dá)開(kāi)始執(zhí)行時(shí),Varnish會(huì)將這些配置轉(zhuǎn)換成二進(jìn)制代碼。
VCL文件被分成多個(gè)子程序。不同的子程序在不同時(shí)候運(yùn)行。有的在獲得請(qǐng)求時(shí)候運(yùn)行,有的當(dāng)文件從后端獲取后運(yùn)行。

Varnish將在它工作的不同場(chǎng)景執(zhí)行這些子程序。因?yàn)槭谴a,所以逐行執(zhí)行并不是問(wèn)題。在某些情況你在這個(gè)子程序調(diào)用一個(gè)action,然后該子程序執(zhí)行結(jié)束。
如果不想在你的子程序中調(diào)用一個(gè)action,并且到達(dá)了最末尾,此時(shí)varnish會(huì)執(zhí)行一些VCL的內(nèi)置代碼。在default.vcl中的注釋部分,你會(huì)看到這些VCL代碼。
99%的情況,你都會(huì)要改動(dòng)兩個(gè)子程序,vcl_recvvcl_fetch
vcl_recv
vcl_recv是在請(qǐng)求開(kāi)始時(shí)調(diào)用的。完成該子程序后,請(qǐng)求就被接收并解析了。用于確定是否需要服務(wù)請(qǐng)求,怎么服務(wù),如果可用,使用哪個(gè)后端。
在vcl_recv中,你也可以修改請(qǐng)求。通常你可以修改cookie,或添加/移除請(qǐng)求頭信息。
注意在vcl_recv中,只可以使用請(qǐng)求對(duì)象req。

vcl_fetch
vcl_fetch是在文檔從后端被成功接收后調(diào)用的。通常用于調(diào)整響應(yīng)頭信息,觸發(fā)ESI處理,萬(wàn)一請(qǐng)求失敗就換個(gè)后端服務(wù)器。
在vcl_fecth中,你還可以使用請(qǐng)求對(duì)象req。還有個(gè)后端響應(yīng)對(duì)象beresp。Beresp包含了后端的HTTP頭信息。
actions
最常用的action如下:
pass:當(dāng)返回pass的時(shí)候,請(qǐng)求和隨后的響應(yīng)都將被傳到后端服務(wù)器,或從那里傳回。不會(huì)被緩存。pass可以在vcl_recv中被返回。
hit_for_pass:類似與pass,但是只有vcl_fetch可以用。不像pass,hit_for_pass將在緩存中創(chuàng)建一個(gè)hitforpass對(duì)象。這有個(gè)副作用,就是緩存了不像緩存的東西。同時(shí)會(huì)將未緩存的請(qǐng)求傳到后端。在vcl_recv中這樣的邏輯不是必須的,因?yàn)樗l(fā)生在任何潛在對(duì)象隊(duì)列發(fā)生之前。
lookup:當(dāng)在vcl_recv中返回lookup時(shí),就等于你告訴varnish發(fā)送緩存中的內(nèi)容,即使該請(qǐng)求應(yīng)該是被pass的。在vcl_fetch中不能使用lookup。
pipe:pipe也可以在vcl_recv中返回。pipe縮短了客戶和后端的環(huán)路鏈接,并且varnish將只是待在哪里,來(lái)回偏移字節(jié)。varnish不會(huì)在意來(lái)回發(fā)送的數(shù)據(jù),所以你的日志是不完整的。注意一個(gè)客戶會(huì)基于相同鏈接發(fā)送幾個(gè)請(qǐng)求,當(dāng)使用HTTP 1.1時(shí)。所以在實(shí)際返回pipe之前,你需要讓varnish添加”Connection:close”的頭信息。
deliver:投遞緩存對(duì)象給客戶。經(jīng)常在vcl_fetch中使用。
請(qǐng)求,響應(yīng)和對(duì)象
在VCL中,有三種重要的數(shù)據(jù)結(jié)構(gòu)。請(qǐng)求:來(lái)自客戶端;響應(yīng):來(lái)自后端服務(wù)器;對(duì)象:存儲(chǔ)在緩存中。
在VCL中你應(yīng)該知道以下結(jié)構(gòu)。
req:請(qǐng)求對(duì)象。當(dāng)varnish接受了請(qǐng)求,req就會(huì)創(chuàng)建并生產(chǎn)。許多在vcl_recv中要做的工作都需要用到req。
beresp:后端響應(yīng)對(duì)象。包含了從后端返回的對(duì)象的頭信息。vcl_fetch中,你會(huì)使用beresp對(duì)象。
obj:緩存了的對(duì)象。大多數(shù)是駐留在內(nèi)存中的只讀對(duì)象。obj.ttl是可以寫(xiě)的,剩下的都是只讀的。
操作符
VCL中可用的操作符如下,稍后可以看例子:
=:賦值
==:比較
~:匹配。可使用正則表達(dá)式或ACLs
!:取反
&&:邏輯與
||:邏輯或
例1 – 操作頭信息
移除所有在web服務(wù)器的/images目錄中的對(duì)象的cookie:

1
2
3
4
5
sub vcl_recv {
if (req.url ~ "^/images") {
unset req.http.cookie;
}
}

現(xiàn)在,當(dāng)請(qǐng)求傳到后端服務(wù)器時(shí),他是不帶有cookie頭信息的。需要在意的是if語(yǔ)句,它根據(jù)正則表達(dá)式匹配了URL(屬于請(qǐng)求對(duì)象)。注意匹配操作符。如果它匹配,請(qǐng)求的cookie頭信息就會(huì)被刪除。
例2 – 操作beresp
這里如果匹配某種條件,我們就重寫(xiě)beresp的TTL屬性

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

例3 – ACLs
你創(chuàng)建了一個(gè)使用acl關(guān)鍵字的訪問(wèn)控制列表。你可以使用匹配操作符去判斷客戶端的IP地址是否與一個(gè)ACL匹配。

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 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.";
}
}


七、Statistics
現(xiàn)在你的varnish已經(jīng)運(yùn)行了,現(xiàn)在讓我們看看它是如何工作的吧。有幾個(gè)工具可以幫助你。
1、 varnishtop
varnishtop工具讀取共享內(nèi)存日志,并且顯示一個(gè)持續(xù)更新的最常見(jiàn)的記錄條的列表。
通過(guò)使用-I,-i,-X和-x選項(xiàng)進(jìn)行適當(dāng)過(guò)濾,可以用于顯示排名,有請(qǐng)求文檔、客戶端、用戶代理(瀏覽器)或其他記錄在日志中的信息。
varnish –i rxurl將顯示客戶端請(qǐng)求的URL。varnishtop –i txurl 將顯示你的后端被什么請(qǐng)求最多。varnishtop –i RxHeader –I Accept-Encoding將顯示最常見(jiàn)的客戶端發(fā)來(lái)的Accept-Encoding header。
2、 varnishhist
varnishhist工具讀取varnishd(1)共享內(nèi)存日志,并且提供不斷更新的直方圖,用以展示它們處理的最近的N個(gè)請(qǐng)求的分布。N值和垂直刻度在左上角顯示。水平刻度是對(duì)數(shù)的。命中用管道符號(hào)(“|”)標(biāo)記,未命中使用哈希符號(hào)(“#”)標(biāo)記。
3、 varnishsizes
varnishsizes和varnishhist相似,但它會(huì)顯示對(duì)象的大小,不顯示完成請(qǐng)求消耗的時(shí)間。可以很直觀的告訴你,你正在處理的對(duì)象有多大。
4、 varnishstat
varnish有很多計(jì)數(shù)器。統(tǒng)計(jì)丟失數(shù),命中數(shù),存儲(chǔ)信息數(shù),創(chuàng)建了的線程數(shù),刪除的對(duì)象數(shù),幾乎一切。varnishstat將轉(zhuǎn)存這些計(jì)數(shù)器。當(dāng)對(duì)varnish進(jìn)行調(diào)優(yōu)時(shí),這就很有用了。
這里有一些程序可以定期獲取varnishstat,很好地繪出這些計(jì)數(shù)器的圖形。Munin是其中一個(gè)。你可以在http://munin-monitoring.org找到。在varnish的源碼中有一個(gè)munin的插件。

八、Achieving a high hitrate
現(xiàn)在Varnish已經(jīng)運(yùn)行,并且你可以通過(guò)Varnish訪問(wèn)你的站點(diǎn)。除非你的應(yīng)用是專門為在一個(gè)web加速器后工作而寫(xiě)的,否則為了在Varnish中獲得高命中率,你可能需要在配置或應(yīng)用上做一些修改。
除非varnish完全確定緩存你的數(shù)據(jù)室安全,否則varnish是不會(huì)緩存的。所以,為了讓你明白varnish是如何確定的,并使如何緩存頁(yè)面的,我將通過(guò)一些很有用工具去引導(dǎo)你:
注意你需要一個(gè)工具去觀察傳輸于你和web服務(wù)器之間的HTTP頭信息。在varnish服務(wù)器上,首先是使用varnishlog和varnishtop,但有時(shí)候需要客戶端工具去搞清楚。下面就是我們用到的。
工具:varnishtop
你可以使用varnishtop確定出后端命中最多的URL。varnishtop –i txurl是必須的命令。你可以在前一節(jié)Statistics中,看到一些其他的varnishtop的例子。
工具:varnishlog
當(dāng)你已經(jīng)確定了最常發(fā)送給后端的URL是多少時(shí),你可以使用varnishlog去查看完整的請(qǐng)求。varnishlog –c –o /foo/bar將給你來(lái)自客戶端(-c)的完整(-o)的匹配/foo/bar的請(qǐng)求。
對(duì)于擴(kuò)展診斷頭信息,可以參看:http://www.varnish-cache.org/trac/wiki/VCLExampleHitMissHeader
工具:lwp-request
lwp-request是perl的World-Wide Web library中的一部分。它是一些基本的程序,這些程序可以處理HTTP請(qǐng)求,并且給你結(jié)果。我通常使用兩個(gè)程序,GET和HEAD。
vg.no是第一個(gè)使用varnish的站點(diǎn),站點(diǎn)的創(chuàng)建者很明白varnish。所以,讓我們看看他們的HTTP頭信息。我們對(duì)他們的首頁(yè)發(fā)一個(gè)GET請(qǐng)求:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
$ GET -H 'Host: www.vg.no' -Used 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-WebCache: joanie
X-VG-WebServer: leon

OK。我們來(lái)解釋一下。GET通常發(fā)送HTTP0.9請(qǐng)求,其缺少Host頭信息。所以我通過(guò)-H添加了一個(gè)Host頭信息。-U打印請(qǐng)求頭信息,-s打印響應(yīng)狀態(tài),-e打印響應(yīng)頭信息,-d丟棄實(shí)際內(nèi)容。我們并不關(guān)心內(nèi)容,只要頭信息。
你可以發(fā)現(xiàn),VG在他們的頭信息中添加了一些信息。像X-Rick-Would-Never表示了vg.no的某種奇怪的幽默。其他,像X-VG-Webcache是用來(lái)調(diào)試的。
所以,你可以檢查一個(gè)站點(diǎn)的特定URL是否設(shè)置了cookie,只需要:

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

工具:實(shí)時(shí)HTTP頭信息
Firefox也有個(gè)插件。Live HTTP Headers可以顯示你發(fā)送和接受到的頭信息。你可以通過(guò)google找到“Live HTTP Header”,或者到https://addons.mozilla.org/en-US/firefox/addon/3829/可以找到。
HTTP頭信息的角色
隨著每個(gè)HTTP請(qǐng)求和響應(yīng)變成一群攜帶原數(shù)據(jù)的頭信息。varnish將查看這些頭信息,以確定這里的內(nèi)容是否適合緩存,以及緩存多久。
請(qǐng)注意,當(dāng)考慮這些頭信息時(shí)候,實(shí)際上varnish只考慮真實(shí)web服務(wù)器中varnish自己的那部分??紤]的理論依據(jù)都在于你的控制。
術(shù)語(yǔ)surrogate origin cache沒(méi)有在IETF so RFC2616中很好的定義。所以varnish不同的工作方式可能會(huì)和你的預(yù)期不同。
讓我們看看你應(yīng)該知道的重要的頭信息:
Cache-Control
Cache-Control指定了緩存如何處理內(nèi)容。varnish關(guān)心max-age參數(shù),并用它來(lái)計(jì)算對(duì)象的TTL。
“Cache-Control:nocache”是被忽略的,如果你需要,你也可以方便的增加支持。
所以,確保你發(fā)出的Cache-Control頭信息具有max-age。你可以看看Varnish軟件的聯(lián)盟服務(wù)器發(fā)出了什么:

1
2
$ GET -Used http://www.varnish-software.com/|grep ^Cache-Control
Cache-Control: public, max-age=600

Age
varnish添加了一個(gè)Age頭信息,以指示在Varnish中該對(duì)象被保持了多久。你可以通過(guò)varnishlog像下面那樣抓出Age:

1
varnishlog -i TxHeader -I ^Age

Pragma
一個(gè)HTTP 1.0服務(wù)器可能會(huì)發(fā)送”Pragma:nocache”。Varnish忽略這種頭信息。在VCL中你可以很方便的增加對(duì)這種頭信息的支持。
在vcl_fetch中:

1
2
3
if (beresp.http.Pragma ~ "nocache") {
pass;
}

Authorization
如果varnish看到授權(quán)頭信息時(shí),它會(huì)pass該請(qǐng)求。如果這不是你希望的,你可以u(píng)nset這個(gè)頭信息。


Overriding the time-to-live(ttl)
有時(shí)你的后端會(huì)誤操作。根據(jù)你的安裝,在varnish中覆寫(xiě)ttl會(huì)比修復(fù)你某些麻煩的后端要簡(jiǎn)單的多。
你需要VCL去確定你想要的對(duì)象,然后你將beresp.ttl的值設(shè)置成你想設(shè)置的值。

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

該例會(huì)為你網(wǎng)站上過(guò)去的遺留物,將TTL設(shè)置為5天。
Forcing caching for certain requests and certain responses
由于你還在使用那些麻煩的不能很好工作的后端,你可能會(huì)想再varnish中覆寫(xiě)更多的內(nèi)容。我們推薦你盡可能多的使用默認(rèn)緩存規(guī)則。盡管強(qiáng)制varnish在緩存中查找一個(gè)對(duì)象很簡(jiǎn)單,但我們還是不推薦。
Normalizing your namespace
一些站點(diǎn)可以通過(guò)很多主機(jī)名訪問(wèn)。比如, http://www.varnish-software.com/ , http://varnish-software.com/和http://varnishsoftware.com/。這些都指向同一個(gè)站點(diǎn)。由于varnish不知道他們的區(qū)別,varnish會(huì)為每個(gè)主機(jī)名的每個(gè)頁(yè)面做緩存。你可以通過(guò)在你的web服務(wù)器配置中設(shè)置跳轉(zhuǎn)或者使用VCL來(lái)緩解這個(gè)情況:

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

Ways of increasing your hitrate even more
接下來(lái)的章節(jié),會(huì)闡述進(jìn)一步提高命中率的方法,尤其在cookies的章節(jié)中。

  • Cookies
  • Vary
  • Purging and banning
  • Edge Side Includes

九、Cookies
varnish不會(huì)緩存來(lái)自后端的具有Set-Cookie頭信息的對(duì)象。同樣,如果客戶端發(fā)送了一個(gè)Cookie頭信息,varnish將繞過(guò)緩存,直接發(fā)給后端。
這可能太過(guò)保守。很多站點(diǎn)使用Google Analytics(GA)去分析他們的流量。GA通過(guò)設(shè)置cookie去跟蹤。這個(gè)cookie是供客戶端的JavaScript程序使用的,服務(wù)器是不需要的。
對(duì)很多web應(yīng)用,它會(huì)完全忽視cookies,除非你正在訪問(wèn)網(wǎng)站的特定部分。在vcl_recv中的下面的VCL代碼塊將忽略cookies,除非你訪問(wèn)/admin/:

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

非常簡(jiǎn)單。然后,如果你需要做更復(fù)雜的處理,像在幾個(gè)cookie中移除其中一個(gè),事情就麻煩了。遺憾的是,varnish沒(méi)有很好的工具去操作cookie。我們不得不使用正則表達(dá)式去做這件事情。如果你熟悉正則表達(dá)式,你就明白怎么辦了。如果你不熟悉,我建議你找本書(shū)好好學(xué)習(xí)下,或者通過(guò)pcrepattern手冊(cè)頁(yè)面或其他的在線教程。
讓我展示給你看看,varnish軟件是用什么的。我們使用一些GA的跟蹤cookie或其他類似工具的cookie。這些cookie都是供JavaScript使用的。varnish和其聯(lián)盟站不需要這些cookie,并且因?yàn)関arnish會(huì)因?yàn)檫@些cookie不緩存頁(yè)面,所以當(dāng)客戶端發(fā)送cookie時(shí),我們將在VCL中丟棄這些非必要的cookie。
下面的VCL中,我們丟棄了所有的以“_”開(kāi)頭的cookie:

1
2
3
4
// 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*", "");

該例取自Varnish的wiki,在那里你可以找到其他使用VCL做的例子。

十、Vary
Vary頭信息是web服務(wù)器發(fā)送的,代表什么引起了HTTP對(duì)象的變化??梢酝ㄟ^(guò)Accept-Encoding這樣的頭信息弄明白。當(dāng)服務(wù)器發(fā)出”Vary:Accept-Encoding”,它等于告訴varnish,需要對(duì)每個(gè)來(lái)自客戶端的不同的Accept-Encoding緩存不同的版本。所以,如果客戶端只接收gzip編碼。varnish就不會(huì)提供deflate編碼的頁(yè)面版本。
如果Accept-Encoding字段含有很多不同的編碼,比如瀏覽器這樣發(fā)送:

1
Accept-Encodign: gzip,deflate

另一個(gè)這樣發(fā)送:

1
Accept-Encoding: deflate,gzip

因?yàn)锳ccept-Encoding頭信息不通,varnish將保存兩種不同的請(qǐng)求頁(yè)面。規(guī)范Accept-Encoding頭信息將確保你的不同盡可能的少。下面的VCL代碼將規(guī)范Accept-Encoding的頭信息:

01
02
03
04
05
06
07
08
09
10
11
12
13
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;
}
}

該代碼設(shè)置了來(lái)自客戶端的Accept-Encoding頭信息,gzip具有更高優(yōu)先級(jí)。

十一、Pitfall – Vary:User-Agent
一些應(yīng)用或應(yīng)用服務(wù)器,會(huì)隨它們的內(nèi)容發(fā)送”Vary:User-Agent”。這指示Varnish對(duì)每個(gè)不同的User-Agent緩存不同的副本。這非常的多。甚至相同瀏覽器的一個(gè)補(bǔ)丁都至少會(huì)產(chǎn)生10中不同的User-Agent頭信息,這個(gè)產(chǎn)生的不同是和瀏覽器所運(yùn)行的操作系統(tǒng)有關(guān)。
所以,如果你真的需要基于User-Agent變化,要確保規(guī)范頭信息,否則你的命中率會(huì)非常的差??梢岳蒙厦娴拇a作為模板。

十二、Purging and banning
最有效提升命中率的方法是增加你對(duì)象的ttl(time-to-live存活時(shí)間)。但是,你要知道,在微博時(shí)代,提供過(guò)時(shí)的內(nèi)容是很不利于業(yè)務(wù)的。
解決方案是,當(dāng)有新內(nèi)容時(shí),就通知varnish。這可以通過(guò)兩個(gè)機(jī)制實(shí)現(xiàn)。HTTP清理(PURGE,以下稱PURGE)和禁止(BAN,以下簡(jiǎn)稱BAN)。首先讓我們解釋下HTTP PURGE
HTTP PURGE
PURGE(清理)是指當(dāng)你選出一個(gè)緩存對(duì)象時(shí),根據(jù)其變化的內(nèi)容進(jìn)行丟棄。通常PURGE是通過(guò)HTTP的PURGE方法進(jìn)行調(diào)用的(即method=purge,這個(gè)purge是http協(xié)議中沒(méi)有預(yù)定義的,應(yīng)該是varnish中擴(kuò)展的)。
HTTP PURGE類似于HTTP GET請(qǐng)求,只是method是PURGE。事實(shí)上,你可以調(diào)用任何你希望的method,不過(guò)許多人都傾向于使用PURGE。Squid支持相同的機(jī)制。為了在varnish支持PURGE,你需要以下代碼:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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。當(dāng)我們調(diào)用lookup時(shí),varnish將嘗試在緩存中查找對(duì)象。要么命中,要么丟失,然后調(diào)用相應(yīng)的子程序。在vcl_hit中,我們可以獲得存于緩存中的對(duì)象,并且可以設(shè)置它的TTL。
所以,對(duì)于example.com,要讓它的首頁(yè)失效(表示要拿新的內(nèi)容),可以這樣請(qǐng)求varnish:

1
2
PURGE / HTTP/1.0
Host: example.com

之后,Varnish就會(huì)丟棄主頁(yè)。這會(huì)移除所有變量,如vary所定義的。
Ban
這是另一個(gè)讓內(nèi)容失效的方法。禁止(BAN),你可以將其認(rèn)為是一種過(guò)濾器。你禁止你的緩存提供某些內(nèi)容。你可以根據(jù)我們有的元數(shù)據(jù),進(jìn)行禁止。
Varnish支持禁止功能,并且可以再CLI接口中獲得。對(duì)于VG,如果想禁止屬于example.com的png對(duì)象,他們可以分發(fā)以下內(nèi)容:

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

真的很強(qiáng)大。
當(dāng)在緩存中命中對(duì)象時(shí)且在投遞之前,就會(huì)檢查其是否BAN。一個(gè)對(duì)象只會(huì)被較新的BAN檢查。
只對(duì)beresp.*起作用的BAN,由背景工作線程運(yùn)行著,稱為ban lurker。ban lurker將檢查堆,看看是否匹配對(duì)象,并且去除匹配對(duì)象。ban lurker的頻度(活躍度),可以通過(guò)ban_lurker_sleep參數(shù)控制。
禁止那些較老的,對(duì)于緩存中最老的對(duì)象不經(jīng)驗(yàn)證就直接丟棄。如果你有很多具有長(zhǎng)TTL對(duì)象,這些對(duì)象很少被訪問(wèn),那么你會(huì)累積大量的禁止。這會(huì)影響CPU的利用率和性能。
你可以通過(guò)HTTP向varnish添加BAN。這樣做需要一些VCL:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
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";
}
}

該VCL代碼段啟用varnish,去處理一個(gè)HTTP BAN method,對(duì)URL添加禁止,包括host部分。

十三、Edge Side Includes
Edge Side Includes(邊界情況包含)是一種語(yǔ)言,用來(lái)包含在其他web頁(yè)面中的web頁(yè)面片斷??梢哉J(rèn)為他是一個(gè)通過(guò)HTTP實(shí)現(xiàn)的HTML包含語(yǔ)句。
在許多web站點(diǎn),許多內(nèi)容是各頁(yè)面間共享的。為每個(gè)頁(yè)面重新生成這些內(nèi)容是很浪費(fèi)的,并且ESI(Edge Side Includes的縮寫(xiě))致力于讓你為每個(gè)片斷單獨(dú)決定緩存策略。
在varnish中,我們只實(shí)現(xiàn)了ESI的一個(gè)小的子集。自2.1起,我們就有三個(gè)ESI語(yǔ)句:

  • esi:include
  • esi:remove
  • <!–esi …–>

基于變量和cookie的內(nèi)容替換還沒(méi)有實(shí)現(xiàn),但是已經(jīng)在計(jì)劃中了。
例子:esi include
讓我們看看如何使用它。這段簡(jiǎn)單的cgi腳本,輸出了日期:

1
2
3
4
5
#!/bin/sh
echo 'Content-type: text/html'
echo ''
date "+%Y-%m-%d %H:%M"

現(xiàn)在,讓我們做個(gè)包含ESI include語(yǔ)句的HTML文件:

1
2
3
4
5
6
<HTML>
<BODY>
The time is: <esi:include src="/cgi-bin/date.cgi"/>
at this very moment.
</BODY>
</HTML>

要讓esi工作,你需要在VCL中激活ESI,比如像下面那樣:

1
2
3
4
5
6
7
8
9
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 remove
該remove關(guān)鍵字,允許你remove輸出。當(dāng)ESI無(wú)法獲得時(shí),你可以使用此,做各種各樣的回退,代碼如下:

例子:<!—esi…–>
這是一個(gè)特殊的構(gòu)造,允許ESI標(biāo)記的HTML呈現(xiàn),而無(wú)需處理。當(dāng)處理頁(yè)面時(shí),ESI處理器將移除開(kāi)始(<–esi)和結(jié)尾(–>),然而仍然會(huì)處理其內(nèi)容。如果頁(yè)面沒(méi)有被處理,它將會(huì)留下,編程HTML/XML的注釋標(biāo)簽。例如:

1
2
3
<!--esi
<p>Warning: ESI Disabled!</p>
</p> -->

這保證了如果沒(méi)有處理ESI標(biāo)記,它也不會(huì)影響最后HTML的呈現(xiàn)。

十四、Running inside a virtual machine(VM)
雖然可以將varnish運(yùn)行在虛擬的硬件上,但是出于高性能,我們不建議這樣。
OpenVz
如果你運(yùn)行在64位OpenVz(或并行VPS),你必須在啟動(dòng)varnish前減少最大棧尺寸。默認(rèn)分配給每個(gè)線程的內(nèi)存有點(diǎn)多,這會(huì)導(dǎo)致varnish隨著線程數(shù)(==流量)增加而down掉。
在啟動(dòng)腳本中,運(yùn)行以下,降低最大棧尺寸:

1
ulimit -s 256


十五、Advanced Backend Configuration
某些情況,你可能需要讓varnish緩存幾個(gè)服務(wù)器的內(nèi)容。你可能希望varnish映射所有URL到一個(gè)或多個(gè)主機(jī)。這里有許多選項(xiàng)。
比如,我們需要引入一個(gè)Java應(yīng)用到PHP網(wǎng)站。我們的Java應(yīng)用會(huì)處理以/java/開(kāi)頭的URL。
我們將東西起起來(lái),運(yùn)行在8000端口?,F(xiàn)在來(lái)看看default.vcl:

1
2
3
4
backend default {
.host = "127.0.0.1";
.port = "8080";
}

我們添加新的后端:

1
2
3
4
backend java {
.host = "127.0.0.1";
.port = "8000";
}

現(xiàn)在我們要指示,發(fā)送不同URL的規(guī)則??纯磛cl_recv:

1
2
3
4
5
6
7
sub vcl_recv {
if (req.url ~ "^/java/") {
set req.backend = java;
} else {
set req.backend = default.
}
}

非常簡(jiǎn)單?,F(xiàn)在先讓我們停一下,考慮一下這里的情況。如你所見(jiàn),你可以根據(jù)任意情況定義如何選擇后端。如果你發(fā)送移動(dòng)設(shè)備的請(qǐng)求到不同的后端,可以做類似的操作,if(req.User-agent ~ /mobile/)

十六、Directors
Director(不知道怎么翻譯合適,所以就保留了)
你也可以將幾個(gè)后端分組為一組后端。這些組稱為directors。這可以提高性能和靈活度。你可以定義幾個(gè)后端,并把它們歸到一個(gè)director中

1
2
3
4
5
6
backend server1 {
.host = "192.168.0.10";
}
backend server2{
.host = "192.168.0.10";
}

現(xiàn)在創(chuàng)建一個(gè)director:

01
02
03
04
05
06
07
08
09
10
director example_director round-robin {
{
.backend = server1;
}
# server2
{
.backend = server2;
}
# foo
}

該director是一個(gè)循環(huán)director。這代表該director將根據(jù)循環(huán)基礎(chǔ)分發(fā)進(jìn)入的請(qǐng)求。這也是一個(gè)隨機(jī)director,它以隨機(jī)風(fēng)格分發(fā)請(qǐng)求。
但是,如果你的一個(gè)服務(wù)器down了怎么辦?varnish可以將所有的請(qǐng)求,指向一個(gè)健康的服務(wù)器嗎?當(dāng)然了。這就是下面要說(shuō)的健康檢查。

十七、Health checks
讓我們建立一個(gè)director,該director具有兩個(gè)后端并帶健康檢查。首先讓我們定義后端:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
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是新的內(nèi)容。varnish將使用probe對(duì)每個(gè)后端進(jìn)行健康檢查。其選項(xiàng)有:
url:定義什么樣的URL需要varnish(感覺(jué)這里應(yīng)該是做處理的意思)請(qǐng)求。
interval:查詢的間隔時(shí)長(zhǎng)
timeout:probe的超時(shí)時(shí)間
window:varnish將保持一個(gè)結(jié)果的滑動(dòng)窗(該滑動(dòng)窗不是實(shí)際的窗體,是一種流量控制方法,允許發(fā)送方在停止并等待確認(rèn)前可以連續(xù)發(fā)送多個(gè)分組。由于發(fā)送方不必每發(fā)一個(gè)分組就停下來(lái)等待確認(rèn),因此該協(xié)議可以加速數(shù)據(jù)的傳輸。)。這里窗口有5個(gè)確認(rèn)點(diǎn)。
threshold:上次查詢的.window數(shù)量為多少時(shí),就代表后端是健康的。
initial:當(dāng)varnish啟動(dòng)時(shí)候,用多少個(gè)probe去探測(cè)健康情況——默認(rèn)情況,此數(shù)量與threshold的數(shù)量一致。
現(xiàn)在我們定義director:

01
02
03
04
05
06
07
08
09
10
director example_director round-robin {
{
.backend = server1;
}
# server2
{
.backend = server2;
}
}

使用這個(gè)director,就通你使用其他director或后端一樣。varnish不會(huì)發(fā)送流量到那些標(biāo)記為不健康主機(jī)。
如果所有的后端都down掉了,varnish也會(huì)提供老的內(nèi)容。關(guān)于如何啟用這個(gè)功能,可以參看Misbehaving servers。
請(qǐng)注意,varnish將為所有已加載的VCL,持續(xù)探測(cè)是否活動(dòng)(active)。varnish將合并相同的probe——所以,注意,如果你做了很多VCL加載,就不要改變probe的配置。卸載VCL,將丟棄probe。

十八、Misbehaving servers
varnish有個(gè)重要的特性,它可以保護(hù)你免受web-和應(yīng)用服務(wù)器的不良行為。
Grace mode
當(dāng)幾個(gè)客戶端正訪問(wèn)相同頁(yè)面時(shí),varnish會(huì)發(fā)送一個(gè)請(qǐng)求到后端,并且讓其他請(qǐng)求等待,當(dāng)從后端取回一個(gè)副本時(shí)。在某些產(chǎn)品中,這稱為請(qǐng)求黑那個(gè),varnish會(huì)自動(dòng)做這個(gè)。
如果你每秒需要相應(yīng)成千上萬(wàn)的點(diǎn)擊,等待的請(qǐng)求隊(duì)列就會(huì)很巨大。這里有兩個(gè)潛在問(wèn)題,一個(gè)是thundering herd problem(這個(gè)無(wú)法翻譯。。。wiki有專門的對(duì)應(yīng)解釋),突然增加一千個(gè)線程去提供內(nèi)容,會(huì)讓負(fù)載變得很高。第二個(gè),沒(méi)有人喜歡等。為了解決這個(gè)問(wèn)題,我們指示varnish去保持緩存的對(duì)象超過(guò)他們的TTL(就是該過(guò)期的,不讓它過(guò)期),并且去提供舊的內(nèi)容給正在等待的請(qǐng)求。
所以,為了提供舊的內(nèi)容,首先我們必須有內(nèi)容去提供。所以,我們使用以下VCL,以使varnish保持所有對(duì)象超出了他們的TTL30分鐘。

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

這樣,varnish還不會(huì)提供舊對(duì)象。為了啟用varnish去提供舊對(duì)象,我們必須在請(qǐng)求上開(kāi)啟它。下面表示,我們接收15s的舊對(duì)象:

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

你可能想知道,為什么,如果我們無(wú)法提供這些對(duì)象,我們?cè)诰彺嬷斜3诌@些對(duì)象30分鐘?如果你開(kāi)啟健康檢查,你可以檢查后端是否出問(wèn)題。如果出問(wèn)題了,我們可以提供長(zhǎng)點(diǎn)時(shí)間的舊內(nèi)容。

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

所以,總結(jié)下,優(yōu)雅模式解決了兩個(gè)問(wèn)題:
1、 通過(guò)提供舊的內(nèi)容,避免請(qǐng)求扎堆。
2、 如果后端壞了,提供舊的內(nèi)容。
Saint mode
有時(shí)候,服務(wù)器會(huì)比較奇怪。他們開(kāi)始拋出隨機(jī)錯(cuò)誤。你可以指示varnish去處 理這些錯(cuò)誤,用一種更加優(yōu)雅得方式——神圣模式。神圣模式可以讓你拋棄一個(gè)后端服務(wù)器的某個(gè)頁(yè)面,并嘗試從其他服務(wù)器獲取,或提供緩存中的舊內(nèi)容。讓我們看看如何在VCL中開(kāi)啟:

1
2
3
4
5
6
7
sub vcl_fetch {
if (beresp.status == 500) {
set beresp.saintmode = 10s;
restart;
}
set beresp.grace = 5m;
}

當(dāng)我們?cè)O(shè)置beresp.saintmode為10秒時(shí),varnish會(huì)不請(qǐng)求該服務(wù)器10秒?;蚨嗷蛏倏梢运闶且粋€(gè)黑名單。restart被執(zhí)行時(shí),如果我們有其他后端可以提供該內(nèi)容,varnish會(huì)請(qǐng)求它們。當(dāng)沒(méi)有其他后端可用,varnish就會(huì)提供緩存中的舊內(nèi)容。
這真的是可以救命的。
清楚grace-和saint 模式的限制
當(dāng)請(qǐng)求正在被獲取時(shí),如果你的請(qǐng)求失敗,會(huì)被扔到vcl_error中。由于vcl_error對(duì)數(shù)據(jù)集的訪問(wèn)有很大顯示,所以你不能啟用優(yōu)雅模式和神圣模式。在以后發(fā)布的版本中會(huì)解決這個(gè)問(wèn)題,但是這里我們還是可以做些什么的。
1、 聲明總是出狀況的后端
2、 在vcl_error中設(shè)置magic marker
3、 重啟事務(wù)
4、 注意vcl_recv中的magic marker,并設(shè)置后端為之前提到的。
5、 varnish現(xiàn)在將提供舊任何可獲得的數(shù)據(jù)

God mode
還沒(méi)有實(shí)現(xiàn)。:-)

十九、Advanced topics
該教程涉及了varnish中的基礎(chǔ)。如果你通讀了它,你現(xiàn)在應(yīng)該已經(jīng)有運(yùn)行varnish的能力了。這里是一個(gè)簡(jiǎn)短的我們?cè)诒窘坛讨袥](méi)有談到的專題概覽。
更多VCL
VCL比至少我們所說(shuō)的要復(fù)雜一點(diǎn)。這里有一些更多我們沒(méi)有談到的子程序和action可用。要查看VCL的完整教程,可以參看VCL的手冊(cè)頁(yè)面——reference-vcl
使用內(nèi)嵌C擴(kuò)展varnish
你可以使用內(nèi)嵌C去擴(kuò)展varnish。注意,這種方式可能會(huì)把varnish搞亂。因?yàn)镃語(yǔ)言在varnish緩存處理中運(yùn)行,所以如果你的代碼出現(xiàn)一點(diǎn)錯(cuò)誤,varnish就會(huì)崩潰。
我看到的第一個(gè)內(nèi)嵌C應(yīng)用是寫(xiě)入syslog:

01
02
03
04
05
06
07
08
09
10
# 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可以通過(guò)把不同頁(yè)面放到一起,緩存、創(chuàng)建web頁(yè)面。這些片斷可以有自己的緩存策略。如果你的網(wǎng)站有一個(gè)顯示最熱的5篇文章的列表,該列表可能被作為片斷緩存起來(lái),并且被包含在其他頁(yè)面中。使用屬性可以很好地提升命中率并降低服務(wù)器負(fù)載。ESI看上去是這樣的:

1
2
3
4
5
6
<HTML>
<BODY>
The time is: <esi:include src="/cgi-bin/date.cgi"/>
at this very moment.
</BODY>
</HTML>

通過(guò)在vcl_fetch中,設(shè)置do_esi為true,來(lái)讓ESI工作:

1
2
3
4
5
sub vcl_fetch {
if (req.url == "/test.html") {
set beresp.do_esi = true; /* Do ESI processing */
}
}


二十、Troubleshooting Varnish
有時(shí)候varnish會(huì)發(fā)神經(jīng)。為了幫助你理解發(fā)生了,這里有一些你可以檢查的地方。varnishlog,/var/log/syslog, /var/log/messages都是varnish會(huì)留下相關(guān)線索的地方。
當(dāng)varnish沒(méi)有啟動(dòng)
有時(shí)varnish會(huì)不啟動(dòng)。在你的機(jī)器上,為何varnish不啟動(dòng),這里有個(gè)經(jīng)常引起的原因。從/dev/null的權(quán)限錯(cuò)誤,到其他進(jìn)程阻塞了端口。
以debug模式啟動(dòng)varnish,查看發(fā)生了什么。
通過(guò)以下代碼啟動(dòng)varnish:

1
# varnishd -f /usr/local/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000 -a 0.0.0.0:8080 -d

注意,-d選項(xiàng)(開(kāi)啟debug模式)。這將給你一些關(guān)于發(fā)生什么的信息。讓我們看看varnish將如何響應(yīng)那些監(jiān)聽(tīng)此端口上的東西:

1
# varnishd -n foo -f /usr/local/etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000 -a 0.0.0.0:8080 -d
01
02
03
04
05
06
07
08
09
10
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.

現(xiàn)在varnish已經(jīng)啟動(dòng)。只有主進(jìn)程運(yùn)行著,在調(diào)試模式下,緩存是不會(huì)運(yùn)行的。現(xiàn)在你正處于控制臺(tái)。你可以通過(guò)分發(fā)“start”,指示主進(jìn)程開(kāi)始緩存。

1
2
3
4
start
bind(): Address already in use
300 22
Could not open sockets

這里我們發(fā)現(xiàn)個(gè)問(wèn)題。有些其他什么綁定在了varnish的HTTP端口上了。如果這沒(méi)有什么幫助,就在IRC上嘗試下trace、truss或come find us。
Varnish崩潰
當(dāng)varnish損壞,子進(jìn)程就會(huì)崩潰。常常母進(jìn)程將通過(guò)再次重啟子進(jìn)程去解決。任何錯(cuò)誤都會(huì)被記錄在syslog中。看上去會(huì)像以下:

1
2
3
4
5
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

尤其是,如果你在Linux上看到“Error in munmap”錯(cuò)誤,你可能需要增加可獲得的映射數(shù)量。Linux被限制最大64k映射(映射表示將文件或其他對(duì)象映射到內(nèi)存)。設(shè)置sysctl.conf中的vm.max_max_count,將使你提高此限制。你可以通過(guò)統(tǒng)計(jì)/proc/$PID/maps的數(shù)量,來(lái)檢查你程序使用的映射數(shù)量。
記錄在這里的,是一個(gè)很奇怪的問(wèn)題。但是充滿希望的Google將提供答案,如果你曾經(jīng)遇到此問(wèn)題的話。
Varnish提示Guru meditation(一種錯(cuò)誤提示方式,見(jiàn)wiki)
首先在varnishlog中,找到相關(guān)日志條目,這可能會(huì)提供一些線索。因?yàn)関arnishlog記錄了很多數(shù)據(jù),所以可能很難查到我們需要的條目。你可以通過(guò)執(zhí)行一下的命令,設(shè)置varnishlog記錄所有的503錯(cuò)誤:

1
$ varnishlog -c -m TxStatus:503

如果錯(cuò)誤只是發(fā)生在一會(huì)兒前,事務(wù)可能還存在于共享內(nèi)存日志碎片中。要讓varnishlog去處理所有共享內(nèi)存日志只要添加-d選項(xiàng):

1
$ varnishlog -d -c -m TxStatus:503

要進(jìn)一步了解不同參數(shù)的解釋和過(guò)濾能力,請(qǐng)看varnishlog手冊(cè)頁(yè)面。
Varnish不緩存
請(qǐng)查看Achieving a high hitrate

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Linux服務(wù)篇--varnish緩存
CentOS 5.5環(huán)境下安裝配置Varnish
Varnish+Nginx搭建緩存服務(wù)器
Varnish應(yīng)用和實(shí)例詳解
反向代理緩存
Varnish
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服