十六、Directors
Director(不知道怎麼翻譯合適,所以就保留了)
你也可以將幾個後端分組爲一組後端。這些組稱爲directors。這可以提高性能和靈活度。你可以定義幾個後端,並把它們歸到一個director中
1 2 3 4 5 6 | backend server1 {
.host = "192.168.0.10" ; } backend server2{
.host = "192.168.0.10" ; } |
現在創建一個director:
01 02 03 04 05 06 07 08 09 10 | director example_director round-robin { {
.backend = server1; } # server2 {
.backend = server2; } # foo } |
該director是一個循環director。這代表該director將根據循環基礎分發進入的請求。這也是一個隨機director,它以隨機風格分發請求。但是,如果你的一個服務器down了怎麼辦?varnish可以將所有的請求,指向一個健康的服務器嗎?當然了。這就是下面要說的健康檢查。
十七、Health checks
讓我們建立一個director,該director具有兩個後端並帶健康檢查。首先讓我們定義後端:
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是新的內容。varnish將使用probe對每個後端進行健康檢查。其選項有:
url:定義什麼樣的URL需要varnish(感覺這裏應該是做處理的意思)請求。
interval:查詢的間隔時長
timeout:probe的超時時間
window:varnish將保持一個結果的滑動窗(該滑動窗不是實際的窗體,是一種流量控制方法,允許發送方在停止並等待確認前可以連續發送多個分組。由於發送方不必每發一個分組就停下來等待確認,因此該協議可以加速數據的傳輸。)。這裏窗口有5個確認點。
threshold:上次查詢的.window數量爲多少時,就代表後端是健康的。
initial:當varnish啓動時候,用多少個probe去探測健康情況——默認情況,此數量與threshold的數量一致。
現在我們定義director:
01 02 03 04 05 06 07 08 09 10 | director example_director round-robin {
{
.backend = server1;
}
# server2
{
.backend = server2;
} } |
使用這個director,就通你使用其他director或後端一樣。varnish不會發送流量到那些標記爲不健康主機。
如果所有的後端都down掉了,varnish也會提供老的內容。關於如何啓用這個功能,可以參看Misbehaving servers。
請注意,varnish將爲所有已加載的VCL,持續探測是否活動(active)。varnish將合併相同的probe——所以,注意,如果你做了很多VCL加載,就不要改變probe的配置。卸載VCL,將丟棄probe。
十八、Misbehaving servers
varnish有個重要的特性,它可以保護你免受web-和應用服務器的不良行爲。
Grace mode
當幾個客戶端正訪問相同頁面時,varnish會發送一個請求到後端,並且讓其他請求等待,當從後端取回一個副本時。在某些產品中,這稱爲請求黑那個,varnish會自動做這個。
如果你每秒需要相應成千上萬的點擊,等待的請求隊列就會很巨大。這裏有兩個潛在問題,一個是thundering herd problem(這個無法翻譯。。。wiki有專門的對應解釋),突然增加一千個線程去提供內容,會讓負載變得很高。第二個,沒有人喜歡等。爲了解決這個問題,我們指示varnish去保持緩存的對象超過他們的TTL(就是該過期的,不讓它過期),並且去提供舊的內容給正在等待的請求。
所以,爲了提供舊的內容,首先我們必須有內容去提供。所以,我們使用以下VCL,以使varnish保持所有對象超出了他們的TTL30分鐘。
1 2 3 | sub vcl_fetch {
set beresp.grace = 30m; } |
這樣,varnish還不會提供舊對象。爲了啓用varnish去提供舊對象,我們必須在請求上開啓它。下面表示,我們接收15s的舊對象:
1 2 3 | sub vcl_recv {
set req.grace = 15s; } |
你可能想知道,爲什麼,如果我們無法提供這些對象,我們在緩存中保持這些對象30分鐘?如果你開啓健康檢查,你可以檢查後端是否出問題。如果出問題了,我們可以提供長點時間的舊內容。
1 2 3 4 5 | if (! req.backend.healthy) {
set req.grace = 5m; } else {
set req.grace = 15s; } |
所以,總結下,優雅模式解決了兩個問題:
1、 通過提供舊的內容,避免請求扎堆。
2、 如果後端壞了,提供舊的內容。
Saint mode
有時候,服務器會比較奇怪。他們開始拋出隨機錯誤。你可以指示varnish去處 理這些錯誤,用一種更加優雅得方式——神聖模式。神聖模式可以讓你拋棄一個後端服務器的某個頁面,並嘗試從其他服務器獲取,或提供緩存中的舊內容。讓我們看看如何在VCL中開啓:
1 2 3 4 5 6 7 | sub vcl_fetch {
if (beresp.status == 500) {
set beresp.saintmode = 10s;
restart;
}
set beresp.grace = 5m; } |
當我們設置beresp.saintmode爲10秒時,varnish會不請求該服務器10秒。或多或少可以算是一個黑名單。restart被執行時,如果我們有其他後端可以提供該內容,varnish會請求它們。當沒有其他後端可用,varnish就會提供緩存中的舊內容。
這真的是可以救命的。
清楚grace-和saint 模式的限制
當請求正在被獲取時,如果你的請求失敗,會被扔到vcl_error中。由於vcl_error對數據集的訪問有很大顯示,所以你不能啓用優雅模式和神聖模式。在以後發佈的版本中會解決這個問題,但是這裏我們還是可以做些什麼的。
1、 聲明總是出狀況的後端
2、 在vcl_error中設置magic marker
3、 重啓事務
4、 注意vcl_recv中的magic marker,並設置後端爲之前提到的。
5、 varnish現在將提供舊任何可獲得的數據
God mode
還沒有實現。:-)
十九、Advanced topics
該教程涉及了varnish中的基礎。如果你通讀了它,你現在應該已經有運行varnish的能力了。這裏是一個簡短的我們在本教程中沒有談到的專題概覽。
更多VCL
VCL比至少我們所說的要複雜一點。這裏有一些更多我們沒有談到的子程序和action可用。要查看VCL的完整教程,可以參看VCL的手冊頁面——reference-vcl
使用內嵌C擴展varnish
你可以使用內嵌C去擴展varnish。注意,這種方式可能會把varnish搞亂。因爲C語言在varnish緩存處理中運行,所以如果你的代碼出現一點錯誤,varnish就會崩潰。
我看到的第一個內嵌C應用是寫入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可以通過把不同頁面放到一起,緩存、創建web頁面。這些片斷可以有自己的緩存策略。如果你的網站有一個顯示最熱的5篇文章的列表,該列表可能被作爲片斷緩存起來,並且被包含在其他頁面中。使用屬性可以很好地提升命中率並降低服務器負載。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 > |
通過在vcl_fetch中,設置do_esi爲true,來讓ESI工作:
1 2 3 4 5 | sub vcl_fetch {
if (req.url == "/test.html" ) {
set beresp.do_esi = true ; /* Do ESI processing */
} } |
二十、Troubleshooting Varnish
有時候varnish會發神經。爲了幫助你理解發生了,這裏有一些你可以檢查的地方。varnishlog,/var/log/syslog, /var/log/messages都是varnish會留下相關線索的地方。
當varnish沒有啓動
有時varnish會不啓動。在你的機器上,爲何varnish不啓動,這裏有個經常引起的原因。從/dev/null的權限錯誤,到其他進程阻塞了端口。
以debug模式啓動varnish,查看發生了什麼。
通過以下代碼啓動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選項(開啓debug模式)。這將給你一些關於發生什麼的信息。讓我們看看varnish將如何響應那些監聽此端口上的東西:
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. |
現在varnish已經啓動。只有主進程運行着,在調試模式下,緩存是不會運行的。現在你正處於控制檯。你可以通過分發“start”,指示主進程開始緩存。
1 2 3 4 | start bind(): Address already in use 300 22 Could not open sockets |
這裏我們發現個問題。有些其他什麼綁定在了varnish的HTTP端口上了。如果這沒有什麼幫助,就在IRC上嘗試下trace、truss或come find us。
Varnish崩潰
當varnish損壞,子進程就會崩潰。常常母進程將通過再次重啓子進程去解決。任何錯誤都會被記錄在syslog中。看上去會像以下:
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”錯誤,你可能需要增加可獲得的映射數量。Linux被限制最大64k映射(映射表示將文件或其他對象映射到內存)。設置sysctl.conf中的vm.max_max_count,將使你提高此限制。你可以通過統計/proc/$PID/maps的數量,來檢查你程序使用的映射數量。
記錄在這裏的,是一個很奇怪的問題。但是充滿希望的Google將提供答案,如果你曾經遇到此問題的話。
Varnish提示Guru meditation(一種錯誤提示方式,見wiki)
首先在varnishlog中,找到相關日誌條目,這可能會提供一些線索。因爲varnishlog記錄了很多數據,所以可能很難查到我們需要的條目。你可以通過執行一下的命令,設置varnishlog記錄所有的503錯誤:
1 | $ varnishlog -c -m TxStatus:503 |
如果錯誤只是發生在一會兒前,事務可能還存在於共享內存日誌碎片中。要讓varnishlog去處理所有共享內存日誌只要添加-d選項:
1 | $ varnishlog -d -c -m TxStatus:503 |
要進一步瞭解不同參數的解釋和過濾能力,請看varnishlog手冊頁面。
Varnish不緩存
請查看Achieving a high hitrate