1、原理特色
css
Varnish是一個輕量級的cache和反向代理軟件,有如下的優缺點:html
(1)基於內存進行緩存,速度比squid的硬盤緩存要快;可是varnish進程一旦出了問題,緩存數據就丟失了,後端的web服務器的壓力會瞬間加大;web
(2)使用自有的VCL(Varnish Configuation Languege)管理,強大靈活;正則表達式
(3)經過管理端口,利用正則表達式刪除指定的緩存;編程
(4)基於內存IO較高,TCP連接釋放快,能夠支持較高的併發;同時,CPU\內存的開銷較高;後端
(5)支持0-60秒的精確緩存時間;緩存
2、安裝Varnish服務器
Varnish的安裝很是簡單,下面逐步介紹:
一、安裝前的準備
Varnish安裝環境以下表1所示:
表1
主機名 操做系統 IP地址
Varnish-server CentOS release 5.4 192.168.12.246
Web-server CentOS release 5.4 192.168.12.26
接着,創建varnish用戶以及用戶組,而且建立Varnish緩存目錄和日誌目錄:
[root@varnish-server ~]#useradd -s /sbin/nologin varnish
[root@varnish-server ~]#mkdir /data/varnish/cache
[root@varnish-server ~]#mkdir /data/varnish/log
[root@varnish-server ~]#chown -R varnish:varnish /data/varnish/cache
[root@varnish-server ~]#chown -R varnish:varnish /data/varnish/log
二、獲取varnish軟件
Varnish的官方站點爲http://varnish-cache.org,這裏面有varnish的最新說明文檔,以及版本升級記錄,今後站點能夠找到varnish在SourceForge的下載連接,目前,varnish的最新版本是Varnish 2.1.2,下載完成後的包名爲varnish-2.1.2.tar.gz,此處咱們就以此版本爲例,進行安裝配置。
三、安裝pcre
若是沒有安裝Pcre,在編譯varnish2.0以上版本時,會提示找不到pcre庫,而pcre庫是爲了兼容正則表達式,因此必須先安裝pcre庫。
[root@varnish-server ~]#tar zxvf pcre-7.9.tar.gz
[root@varnish-server ~]#cd pcre-7.9/
[root@varnish-server ~]#./configure --prefix=/usr/local/pcre/
[root@varnish-server ~]#make && make install
四、安裝varnish
這裏咱們將varnish安裝到/usr/local/目錄下,操做以下:
[root@varnish-server ~]#tar -zxvf varnish-2.1.2.tar.gz
[root@varnish-server ~]#cd varnish-2.1.2
[root@varnish-server ~]#export PKG_CONFIG_PATH=/usr/local/pcre/lib/pkgconfig
[root@varnish-server ~]#./configure --prefix=/usr/local/varnish \
>--enable-dependency-trackin
>--enable-debugging-symbols
>--enable-developer-warnings
[root@varnish-server ~]#make
[root@varnish-server ~]#make install
[root@varnish-server ~]#cp redhat/varnish.initrc /etc/init.d/varnish
[root@varnish-server ~]#cp redhat/varnish.sysconfig /etc/sysconfig/varnish
其中,「PKG_CONFIG_PATH」是指定varnish查找pcre庫的路徑,若是pcre安裝在了其它路徑下,在這裏指定相應的路徑便可,Varnish默認查找的pcre庫路徑爲/usr/local/lib/ pkgconfig。最後兩步操做是拷貝一些varnish守護進程的初始化腳本文件,這些腳本用於varnish的啓動、關閉管理等方面,在下面章節中會進行詳細講解。
至此,varnish安裝完畢。
併發
3、配置Varnishjsp
一、VCL使用說明
VCL,即爲Varnish Configuation Language,用來定義varnish的存取策略,VCL語法比較簡單,跟C和perl比較類似,可使用指定運算符「=」,比較運算符「==」,邏輯運算符「!,&&,!!」等形式。還支持正則表達樣和用「~」進行ACL匹配運算,同時還可使用「set」這樣的關鍵字來指定變量。
須要注意的是,「\」字符在VCL裏沒有特別的含義,這點與其它語言略有不一樣,另外,VCL只是配置,並非真正的編程語言,沒有循環,也沒有自定義變量。
在講述Varnish配置以前,首先須要瞭解下varnish的配置語法,即VCL,下面對VCL經常使用的一些內置函數和公用變量進行詳細介紹。
VCL內置函數
(1)vcl_recv函數
用於接收和處理請求,當請求到達併成功接收後被調用,經過判斷請求的數據來決定如何處理請求。
此函數通常以以下幾個關鍵字結束:
pass:表示進入pass模式,把請求控制權交給vcl_pass函數。
pipe:表示進入pipe模式,把請求控制權交給vcl_pipe函數。
error code [reason]:表示返回「code」給客戶端,並放棄處理該請求,「code」是錯誤標識,例如200、405等,「reason」是錯誤提示信息。
(2)vcl_pipe函數
此函數在進入pipe模式時被調用,用於將請求直接傳遞至後端主機,在請求和返回的內容沒有改變的狀況下,將不變的內容返回給客戶端,直到這個連接關閉。
此函數通常以以下幾個關鍵字結束:
error code [reason]
pipe
(3)vcl_pass函數
此函數在進入pass模式時被調用,用於將請求直接傳遞至後端主機,後端主機應答數據後送給客戶端,但不進行任何緩存,在當前鏈接下每次都返回最新的內容。
此函數通常以以下幾個關鍵字結束:
error code [reason]
pass
(4)lookup
表示在緩存裏查找被請求的對象,而且根據查找的結果把控制權交給函數vcl_hit或者函數vcl_miss。
(5)vcl_hit函數
在執行lookup指令後,若是在緩存中找到請求的內容,將自動調用該函數。
此函數通常以以下幾個關鍵字結束:
deliver:表示將找到的內容發送給客戶端,並把控制權交給函數vcl_deliver。
error code [reason]
pass
(6)vcl_miss函數
在執行lookup指令後,若是沒有在緩存中找到請求的內容時自動調用該方法,此函數能夠用於判斷是否須要從後端服務器取內容。
此函數通常以以下幾個關鍵字結束:
fetch:表示從後端獲取請求的內容,並把控制權交給vcl_fetch函數。
error code [reason]
pass
(7)vcl_fetch函數
在從後端主機更新緩存而且獲取內容後調用該方法,接着,經過判斷獲取的內容來決定是否將內容放入緩存,仍是直接返回給客戶端。
此函數通常以以下幾個關鍵字結束:
error code [reason]
pass
deliver
(8)vcl_deliver函數
在緩存中找到請求的內容後,發送給客戶端前調用此方法。此函數通常以以下幾個關鍵字結束:
error code [reason]
deliver
(9)vcl_timeout 函數
此函數在緩存內容到期前調用。通常以以下幾個關鍵字結束:
discard:表示從緩存中清除該內容。
fetch
(10)vcl_discard函數
在緩存內容到期後或緩存空間不夠時,自動調用該方法,通常以以下幾個關鍵字結束:
keep:表示將內容繼續保留在緩存中。
discard
3、VCL和Varnish處理http請求的流程
經過上面對VCL函數的介紹,讀者對各個函數實現的功能已經有了一個瞭解,其實每一個函數之間都是相互關聯的,下圖列出了varnish處理HTTP請求的一個運行流程圖。
處理過程大體分爲以下幾個步驟:
(1) Receive狀態,也就是請求處理的入口狀態,根據VCL規則判斷該請求應該是Pass或Pipe,或者進入Lookup(本地查詢)。
(2) Lookup狀態,進入此狀態後,會在hash表中查找數據,若找到,則進入Hit狀態,不然進入miss狀態。
(3) Pass狀態,在此狀態下,會進入後端請求,即進入fetch狀態。
(4) Fetch狀態,在Fetch狀態下,對請求進行後端的獲取,發送請求,得到數據,並進行本地的存儲。
(5) Deliver狀態, 將獲取到的數據發送給客戶端,而後完成本次請求。
三、內置公用變量
VCL內置的公用變量能夠用在不一樣的VCL函數中,根據這些公用變量使用的不一樣階段,下面依次介紹。
當請求到達後,可使用的公用變量如表2所示:
表2
公用變量名稱 含義
req.backend 指定對應的後端主機
server.ip 表示服務器端IP
client.ip 表示客戶端IP
req.request 指定請求的類型,例如GET、HEAD、POST等
req.url 指定請求的地址
req.proto 表示客戶端發起請求的HTTP協議版本
req.http.header 表示對應請求中的http頭部信息
req. restarts 表示請求重啓的次數,默認最大值爲4
Varnish 在向後端主機請求時,可使用的公用變量如表3所示:
表3
公用變量名稱 含義
beresp.request 指定請求的類型,例如GET、HEAD等
beresp.url 指定請求的地址
beresp .proto 表示客戶端發起請求的HTTP協議版本
beresp .http.header 表示對應請求中的http頭部信息
beresp .ttl 表示緩存的生存週期,也就是cache保留多長時間,單位是秒
從cache或者後端主機獲取內容後,可使用的公用變量如表4所示:
表4
公用變量名稱 含義
obj.status 表示返回內容的請求狀態代碼,例如200、30二、504等
obj.cacheable 表示返回的內容是否能夠緩存,也就是說,若是HTTP返回是200、20三、300、30一、30二、40四、410等,而且有非0的生存期,則能夠緩存
obj.valid 表示是不是有效的HTTP應答
obj.response 表示返回內容的請求狀態信息
obj.proto 表示返回內容的HTTP協議版本
obj.ttl 表示返回內容的生存週期,也就是緩存時間,單位是秒
obj.lastuse 表示返回上一次請求到如今的間隔時間,單位是秒
對客戶端應答時,可使用的公用變量如表5所示:
表5
公用變量名稱 含義
resp.status 表示返回給客戶端的HTTP狀態代碼
resp.proto 表示返回給客戶端的HTTP協議版本
resp.http.header 表示返回給客戶端的HTTP頭部信息
resp.response 表示返回給客戶端的HTTP狀態信息
在上面的講述中,咱們只是介紹了經常使用的VCL內置公用變量,若是須要了解和使用更多的公用變量信息,請登陸varnish官方網站查閱。
4、配置一個簡單的Varnish實例
因爲版本的不一樣,Varnish配置文件的寫法也存在必定差別,varnish2.x版本和1.x版本之間不但配置文件寫法不一樣,並且新的版本功能也增長不少,而且去除了不少應用BUG,這裏講述的版本是varnish2.1.2,配置文件寫法也以varnish2.x版本爲基準。
Varnish安裝完成後,默認的配置文件爲/usr/local/varnish/etc/varnish/default.vcl,此文件內容默認所有被註釋掉了,這裏,咱們以這個文件爲模板,建立一個新的文件vcl.conf,而且放到/usr/local/varnish/etc目錄下,配置完成的vcl.conf文件以下:
#經過backend定義了一個名稱爲webserver的後端主機,「.host」指定後端主機的IP地址或者域名,「.port」指定後端主機的服務端口。其中,「192.168.12.26」就是後端的一個web服務器。
backend webserver {
.host = "192.168.12.26";
.port = "80";
}
#調用vcl_recv開始。
sub vcl_recv {
if (req.http.x-forwarded-for) {
set req.http.X-Forwarded-For =
req.http.X-Forwarded-For ", " client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
#若是請求的類型不是GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE時,進入pipe模式。注意這裏是「&&」的關係。
if (req.request != "GET" &&
req.request != "HEAD" &&
req.request != "PUT" &&
req.request != "POST" &&
req.request != "TRACE" &&
req.request != "OPTIONS" &&
req.request != "DELETE") {
return (pipe);
}
#若是請求的類型不是GET與HEAD,則進入pass模式。
if (req.request != "GET" && req.request != "HEAD") {
return (pass);
}
#對ixdba.net或者ixdba.cn兩個域名進行緩存加速,這是個泛域名的概念,也就是全部以ixdba.net或者ixdba.cn結尾的域名都進行緩存。
if (req.http.host ~ "^(.*).ixdba.net" || req.http.host ~ "^(.*).ixdba.cn") {
set req.backend = webserver;
}
#對以.jsp和.do結尾以及帶有?的URL時,直接從後端服務器讀取內容。
if (req.url ~ "\.(jsp|do)($|\?)") {
return (pass);
} else {
return (lookup);
}
}
sub vcl_pipe {
return (pipe);
}
sub vcl_pass {
return (pass);
}
sub vcl_hash {
set req.hash += req.url;
if (req.http.host) {
set req.hash += req.http.host;
} else {
set req.hash += server.ip;
}
return (hash);
}
sub vcl_hit {
if (!obj.cacheable) {
return (pass);
}
return (deliver);
}
sub vcl_miss {
return (fetch);
}
sub vcl_fetch {
if (!beresp.cacheable) {
return (pass);
}
if (beresp.http.Set-Cookie) {
return (pass);
}
#當url中包含servlet時,不進行緩存。
if (req.url ~ "^/servlet/") {
return (pass);
}
#當url中包含services時,不進行緩存。
if (req.url ~ "^/services/") {
return (pass);
}
#對於請求類型是GET,而且請求的URL中包含upload,那麼就進行緩存,緩存的時間是300秒,即5分鐘。
if (req.request == "GET" && req.url ~ "^/upload(.*)$") {
set beresp.ttl = 300s;
}
#對於請求類型是GET,而且請求的URL以png、xsl、xml、gif、css、js等結尾時,則進行緩存,緩存時間爲600秒。
if (req.request == "GET" && req.url ~ "\.(png|xsl|xml|pdf|ppt|doc|docx|chm|rar|zip|bmp|jpeg|swf|ico|mp3|mp4|rmvb|ogg|mov|avi|wmv|swf|txt|png|gif|jpg|css|js|html|htm)$") {
set beresp.ttl = 600s;
}
return (deliver);
}
#下面是添加一個Header標識,以判斷緩存是否命中。
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from www.ixdba.net";
} else {
set resp.http.X-Cache = "MISS from www.ixdba.net";
}
return (deliver);
}