天天看點

varnish基礎環境部署Error "} obj.status " " obj.response {"

#  create by bdkyr  

#  date 2014-8-10

#  參考網上資源修改的配置檔案參數

一、硬體環境

    lenovo RD540

二、軟體環境

server              OS                 IP

Varnish-server  CentOS 5.8        192.168.12.246

Web-server      CentOS  5.8       192.168.12.26

三、部署

3.1建立varnish使用者以及使用者組

   useradd  -s /sbin/nologin varnish

3.2建立Varnish緩存目錄和日志目錄:

mkdir /data/varnish/cache

mkdir /data/varnish/log

chown -R varnish:varnish  /data/varnish/cache

chown -R varnish:varnish  /data/varnish/log

3.3下載下傳varnish軟體

3.3.1安裝pcre,相容正規表達式。

    unzip pcre-8.31.zip

    cd pcre-8.31

    ./configure --prefix=/usr/local/pcre/

    make && make install

    cd ..

3.3.2安裝varnish

    cd /home/xuekun/soft

    wget https://repo.varnish-cache.org/source/varnish-4.0.0.tar.gz

    tar zxvf varnish-4.0.0.tar.gz

    cd varnish-4.0.0

    export PKG_CONFIG_PATH=/usr/local/pcre/lib/pkgconfig

    ./configure --prefix=/application/varnish-4.0.0 \

    --enable-dependency-tracking \

    --enable-debugging-symbols \

    --enable-developer-warnings

    ln -s /application/varnish-4.0.0 /application/varnish

    mkdir /application/varnish/etc

    cp redhat/varnish.initrc  /etc/init.d/varnish

    cp redhat/varnish.sysconfig  /etc/sysconfig/varnish

    cp etc/example.vcl /application/varnish/etc/varnish_vcl.conf

    cd ../

    說明:“PKG_CONFIG_PATH”是指定varnish查找pcre庫的路徑,

    如果pcre安裝在了其它路徑下,在這裡指定相應的路徑即可,

    Varnish預設查找的pcre庫路徑為/usr/local/lib/ pkgconfig。

    最後兩步操作是拷貝一些varnish守護程序的初始化腳本檔案,

    這些腳本用于varnish的啟動、關閉管理等方面,至此,varnish安裝完畢。

四、配置Varnish

4.1、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模式時被調用,用于将請求直接傳遞至後端主機,後端主機應答資料後送給用戶端,但不進行任何緩存,在目前連接配接下每次都傳回最新的内容。

? pass

(4)lookup

表示在緩存裡查找被請求的對象,并且根據查找的結果把控制權交給函數vcl_hit或者函數vcl_miss。

(5)vcl_hit函數

在執行lookup指令後,如果在緩存中找到請求的内容,将自動調用該函數。

? deliver:表示将找到的内容發送給用戶端,并把控制權交給函數vcl_deliver。

(6)vcl_miss函數

在執行lookup指令後,如果沒有在緩存中找到請求的内容時自動調用該方法,此函數可以用于判斷是否需要從後端伺服器取内容。

? fetch:表示從後端擷取請求的内容,并把控制權交給vcl_fetch函數。

(7)vcl_fetch函數

在從後端主機更新緩存并且擷取内容後調用該方法,接着,通過判斷擷取的内容來決定是否将内容放入緩存,還是直接傳回給用戶端。

? deliver

(8)vcl_deliver函數

在緩存中找到請求的内容後,發送給用戶端前調用此方法。此函數一般以如下幾個關鍵字結束:

(9)vcl_timeout 函數

此函數在緩存内容到期前調用。一般以如下幾個關鍵字結束:

? discard:表示從緩存中清除該内容。

? fetch

(10)vcl_discard函數

在緩存内容到期後或緩存空間不夠時,自動調用該方法,一般以如下幾個關鍵字結束:

? keep:表示将内容繼續保留在緩存中。

? discard

4.2、VCL處理流程圖

 通過上面對VCL函數的介紹,讀者對各個函數實作的功能已經有了一個了解,其實每個函數之間都是互相關聯的,下圖列出了varnish處理HTTP請求的一個運作流程圖。

處理過程大緻分為如下幾個步驟:

(1) Receive狀态,也就是請求處理的入口狀态,根據VCL規則判斷該請求應該是Pass或Pipe,或者進入Lookup(本地查詢)。

(2) Lookup狀态,進入此狀态後,會在hash表中查找資料,若找到,則進入Hit狀态,否則進入miss狀态。

(3) Pass狀态,在此狀态下,會進入後端請求,即進入fetch狀态。

(4) Fetch狀态,在Fetch狀态下,對請求進行後端的擷取,發送請求,獲得資料,并進行本地的存儲。

(5) Deliver狀态, 将擷取到的資料發送給用戶端,然後完成本次請求。

4.3、内置公用變量

 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、302、504等

obj.cacheable 表示傳回的内容是否可以緩存,也就是說,如果HTTP傳回是200、203、300、301、302、404、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官方網站查閱。

五 、配置一個簡單的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 (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) {

#當url中包含servlet時,不進行緩存。

    if (req.url ~ "^/servlet/") {

#當url中包含services時,不進行緩存。

    if (req.url ~ "^/services/") {

#對于請求類型是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;

  #下面是添加一個Header辨別,以判斷緩存是否命中。

sub vcl_deliver {

    if (obj.hits > 0) {

       set resp.http.X-Cache = "HIT from www.bdkyr.com";

      set resp.http.X-Cache = "MISS from www.bdkyr.com";

#############################

backend www {

.host = "www.bdkyr.com";

.port = "80";

acl purge {

"localhost";

"127.0.0.1";

"172.16.2.0"/24;

if (req.restarts == 0) {

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;

if (req.request != "GET" &&

req.request != "HEAD" &&

req.request != "PUT" &&

req.request != "POST" &&

req.request != "TRACE" &&

req.request != "OPTIONS" &&

req.request != "DELETE") {

/* Non-RFC2616 or CONNECT which is weird. */

return (pipe);

if (req.request != "GET" && req.request != "HEAD") {

/* We only deal with GET and HEAD by default */

return (pass);

if (req.http.Authorization || req.http.Cookie) {

/* Not cacheable by default */

else {

lookup;

return (lookup);

set req.hash += req.url;

if (req.http.host) {

set req.hash += req.http.host;

set req.hash += server.ip;

return (hash);

if (!obj.cacheable) {

return (deliver);

return (fetch);

if (!beresp.cacheable) {

if (beresp.http.Set-Cookie) {

sub vcl_error {

set obj.http.Content-Type = "text/html; charset=utf-8";

synthetic {"

<?xml version="1.0" encoding="utf-8"?>

br />

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

"} obj.status " " obj.response {"

"} obj.response {"

XID: "} req.xid {"

Varnish cache server

繼續閱讀