Varnish

varnishhtml

1、簡介
web

   Varnish是一款高性能的開源HTTP加速器,挪威最大的在線報紙 Verdens Gang 使用3臺Varnish代替了原來的12臺Squid,性能比之前更好。
正則表達式

   Varnish 的做者Poul-Henning Kamp是FreeBSD的內核開發者之一,他認爲如今的計算機比起1975年已經複雜許多。在1975年時,儲存媒介只有兩種:內存與硬盤。但如今計算機系統的內存除了主存外,還包括了CPU內的L一、L2,甚至有L3快取。硬盤上也有本身的快取裝置,所以Squid Cache自行處理物件替換的架構不可能得知這些狀況而作到最佳化,但操做系統能夠得知這些狀況,因此這部份的工做應該交給操做系統處理,這就是 Varnish cache設計架構。express

   varnish項目是2006年發佈的第一個版本0.9.距今已經八年多了,此文檔以前也提過varnish還不穩定,那是2007年時候編寫的,通過varnish開發團隊和網友們的辛苦耕耘,如今的varnish已經很健壯。不少門戶網站已經部署了varnish,而且反應都很好,甚至反應比squid還穩定,且效率更高,資源佔用更少。相信在反向代理,web加速方面,varnish已經有足夠能力代替squid。編程

   varnish的官網爲https://www.varnish-cache.org,rpm,rpm包的下載位置爲:http://repo.varnish-cache.org。json

2、關於Varnish後端

1.varnish系統架構
緩存

   varnish主要運行兩個進程:Management進程和Child進程(也叫Cache進程)。
安全

   Management進程主要實現應用新的配置、編譯VCL、監控varnish、初始化varnish以及提供一個命令行接口等。Management進程會每隔一段時間探測一下Child進程以判斷其是否正常運行,若是在指定的時長內未獲得Child進程的迴應,Mangagement將會重啓此Child進程。
服務器

   Child進程包含多種類型的線程,常見的如:

       Acceptor進程:接受新的鏈接請求並響應

       worker進程:child進程會爲每一個用戶啓動一個worker進程,所以,在高併發的場景中可能會出現數百個worker進程甚至更多

       Expiry進程:從緩存中清理過時內容

       Varnish依賴「工做區(workspace)」以下降線程在申請或修改內存時出現競爭的可能性。在varnish內部有多種不一樣的工做區,其中最關鍵的當屬用於管理會話數據的session工做區

2.varnish日誌

   爲了與系統的其餘部分進行交互,Child進程使用了能夠經過文件系統接口進行訪問的共享內存日誌(shared memory log),所以,若是某線程須要記錄信息,其僅須要持有一個鎖,然後向共享內存中的某內存區域寫入數據,再釋放持有的鎖便可。而爲了減小競爭,每一個worker線程都使用了日誌數據緩存

   共享內存大小通常爲90M,其分爲兩部分,前一部分爲計數器,後半部分爲客戶端請求的數據。varnish經過了多個不一樣的工具,如varnishlog、varnishncsa或varnishstst等來分析共享內存日誌中的信息並可以以指定的方式進行顯示

   3.varnish的後端存儲

     varnish支持多種不一樣類型的後端存儲。這能夠在varnish啓動時使用-s選項指定。後端存儲的類型包括

     (1)file:使用特定的文件存儲所有的緩存數據,並經過操做系統的mmap()系統調用整個緩存文件映射至內存區域(若是條件容許)

     (2)mallco: 使用mallco()庫調用在varnish啓動時向操做系統申請指定的大小的內存空間以存儲緩存數據

     (3)persistent(experimental):與file的功能相同,可是能夠持久存儲數據(即重啓varnish時數據不會被清楚),仍處於測試階段

     varnish沒法追蹤某緩存對象是否存入了緩存文件,然後也就沒法得知磁盤上的緩存文件是否可用,所以,file存儲在varnish中止或重啓是會清除數據。而persistent方法的出現對此有一個彌補,但persistent仍處於測試階段,例如目前尚沒法有效處理要緩存對象整體大小超出緩存空間的狀況,全部,其僅適用於有着巨大緩存空間的場景。

    選擇使用合適的存儲方式有助於途勝系統性能,從經驗的角度來看,建議在內存空間足以存儲全部數據的緩存對象時使用malloc的方法,反之,file存儲將會有着更好的性能表現,然而,須要注意的是,varnishd其實是用的空間比使用-s選項指定的緩存空間更大,通常說來,其須要爲每一個緩存對象多使用差很少1k左右的存儲空間,這意味着,對於100萬個緩存對象來講,其使用的緩存空間將超出指定大小1G左右,另外,爲了保存數據結構等,varnish自身也會佔去很多的內存空間。

    爲varnish指定使用的緩存類型時,-s選項可接受的參數格式以下:

       malloc[,size]或file[,path[,size[,granularity]]]或persistent,path,size{experimental}

3、VCL

   1.簡介

     VCL(Varnish Configuration Language)是varnish配置緩存策略的工具,它是一種基於「域」(domain specific)的簡單編程語言,他支持有限的算術運算和邏輯運算操做、容許使用正則表達式進行字符串匹配、容許用戶使用set自定義變量、支持if判斷語句,也要內置的函數和變量等。使用VCL編寫的緩存策略一般保存至.vcl文件中,其須要編譯成二進制的格式後纔能有varnish調用。事實上,整個緩存策略就是由幾個特定的子歷程如vcl_recv、vcl_fetch等組成,他們分別在不一樣的位置(或時間)執行,若是沒有實現爲某個位置自定義子例程,varnish將會執行默認的定義

    VCL策略在啓用前,會由management進程將其轉換爲C代碼,然後再有gcc編譯器將C代碼編譯成二進制程序。編譯完成後,management負責將其鏈接至varnish實例,即Child進程。正式因爲編譯工做在child進程以外完成,它避免了轉載錯誤格式VCL的風險,所以,varnish修改配置的開銷很是小,其能夠同時保有幾分尚在引用的舊版本配置,也可以讓新的配置即刻生效,編譯後的舊版本配置一般在varnish重啓時纔會被丟棄,若是須要手動清理,則可使用varnishadm的vcl.discard命令來完成

2.VCL狀態引擎

    在VCL狀態引擎中,狀態之間具備相關性,但彼此間互相隔離,每一個引擎使用return(x)來退出當前狀態並指示varnish進入下一個狀態

    varnish開始處理一個請求時,首先須要分析HTTP請求自己,好比從首部獲取請求方法、驗證其是否爲一個合法的HTTP請求等,當這些基本分析結束後就須要作出第一個決策,即varnish是否從緩存中查找請求的資源,這個決定的實現則須要有VCL來完成,簡單來講,要有vcl_recv方法來完成,若是說管理員沒有定義vcl_recv函數,varnish將會執行默認的vcl_recv函數,然而,即使管理員自定義了vcl_recv,但若是沒有爲自定義的vcl_recv函數指定其終止操做(terminating),其仍將會指定默認的vcl_recv函數,事實上,varnish官方強烈建議讓varnish執行默認的vcl_recv以便處理自定義vcl_recv函數中可能出現的漏洞

3.VCL語法

    VCL的設計參考了C和perl語言,所以,對有着C或Perl編程經驗者來講,其很是容易理解。其基本語法說明以下:

    (1)//、#或/* comment */用於註釋

    (2)sub $name 定義函數

    (3)不支持循環,有內置變量

    (4)使用終止語句,沒有返回值

    (5)域專用

    (6)操做符:=(賦值)、==(等值比較)、~(模式匹配)、!(非,取反)、&&(邏輯與)、||(邏輯或)

    VCL的函數不接受參數而且沒有返回值,所以,其並不是真正意義上的函數,這也限定了VCL內部的數據傳遞只能隱藏在HTTP首部內部進行。VCL的return語句用於將控制權從VCL狀態引擎返回給varnish,而非默認函數,這就是爲何VCL只有終止語句而沒有返回值的緣由,同時,對於每一個「域」來講,能夠定義一個或多個終止語句,以告訴varnish下一步採起何種操做,如查詢緩存或不查詢緩存

4.VCL的內置函數

     VCL提供告終果函數來實現字符串的修改,如添加bans,重啓VCL狀態引擎因將控制權轉回varnish等

    regsub(str,reget,sub):基於正則表達式搜索指定的字符串並將其替換成指定的字符串,只替換匹配到的第一個

    regsuball(str,reget,sub):基於正則表達式搜索指定的字符串並將其通通替換成指定的字符串

    ban(expression):

    ban_url(regex):Bans全部其URL可以由regex匹配的緩存對象

    purge:從緩存中挑選出某對象以及其相關變種一併刪除,這能夠經過經過HYTP協議的PURGE方法完成

    hash_data(str):

    return():當某個VCL與運行結束時,將控制權返回給Varnish,並指示Varnish如何進行後續的操做:其能夠返回的指令包括:lookup、pass、pipe、hit_for_pass、fetch、deliver和hash等:但某特定域可能技能返回某些特定的指令,而非前面列出的所有指令:

    return(restart):從新運行整個VCL,即從新從vcl_recv開始進行處理;每一次重啓都會增長req.restaets變量中的值,而max_restaets參數則用於限定最大重啓次數

5.vcl_recv

     vcl_recv是在varnish完成對請求報文的解碼爲基本數據結構後第一個要指定的子例程,他一般有四個主要用途:

     (1)修改客戶端數據以減小緩存對象差別性,好比刪除URL中的www.等字符串

      (2)基於客戶端數據選用緩存策略:好比僅緩存特定的額URL請求、不緩存POST請求等

     (3)爲某web應用程序執行URL重寫

     (4)挑選合適的後端服務器;

    可使用下面的終止語句,即經過return()向varnish返回指示操做

      pass:繞過緩存,即不從緩存中查詢內容或不將內容存儲至緩存中;

      pipe:不對客戶端進行檢查或作出任何操做,而是在客戶端與後端服務器之間創建專業「通道」,並直接將數據在兩者之間進行傳送:此時,keep-alive鏈接中後續傳送的數據也都將在經過此管道進行直接傳送,並不會出如今任何日誌中

      lookup:在緩存中查找用戶請求的對象,若是緩存中沒有其指定的對象,後續操做極可能會將其請求的對象進行緩存

      error:有varnish本身合成一個響應報文,通常是響應一個錯誤類信息、重定向類信息或緩存均衡器返回的後端web服務器健康狀態檢查類信息

     vcl_recv也能夠經過精巧的策略完成必定意義上的安全功能,以將某特定的***扼殺於搖籃中,同時,它也能夠檢查出一些拼寫的錯誤並將其進行修改

     varnish默認的vcl_recv專門設計用來實現安全的緩策略,它主要完成兩種功能:

       (1)僅處理能夠識別的HTTP方法,而且只緩存GET和HEAD方法

       (2)不緩存任何用戶特有的數據

     安全起見,通常都在自定義的vcl_recv中不要使用return()終止語句,而是再由默認vcl_recv進行處理,並有其作出響應的的處理決策

6.vcl_fetch

     如前面所述,想對於vcl_recv是根據客戶端的請求作出緩存策略來講,vcl_fetch則是根據服務器端的響應作出緩存決策,在任何VCL狀態引擎中發揮pass操做都將有vcl_fetch進行後續處理。vcl_fetch中有許多可用的內置變量,好比最多見的用於定義某對象緩存時長的beresp.ttl變量,經過return()返回給varnish的操做指令有:

       deliver:緩存此對象,並將其發送給客戶端(經由vcl_deliver)

       hit_for_pass:不緩存此對象,但能夠致使後續對此對象的請求直接送達到vcl_pass進行處理

       restart:重啓整個VCL,並增長重啓次數,超出max_restarts限定的最大重啓次數將會發揮錯誤信息

       error code [reson]:返回指定的錯誤代碼給客戶端並丟棄此請求,「code」是錯誤標識,例如200、405等,「reason」是錯誤提示信息。

      默認的vcl_fetch放棄了緩存任何使用了Set-Cookie首部的響應

7.vcl_deliver

     在緩存中找到緩存內容,發送給客戶端時調用此參數,經過return()返回給varnish的操做指令有:  

       deliver:緩存此對象,並將其發送給客戶端(經由vcl_deliver)

       error code [reson]:返回指定的錯誤代碼給客戶端並丟棄此請求,「code」是錯誤標識,例如200、405等,「reason」是錯誤提示信息。

8.val_pass

      此函數在進入pass模式時被調用,用於將請求直接傳遞至後端主機,後端主機應答數據後發送給客戶端,可是不緩存任何數據,在當前鏈接下,每次都是犯回最新的內容,經過return()返回給varnish的操做指令有:  

        error code [reson]:返回指定的錯誤代碼給客戶端並丟棄此請求,「code」是錯誤標識,例如200、405等,「reason」是錯誤提示信息。

        pass:繞過緩存,即不從緩存中查詢內容或不將內容存儲至緩存中;

9.vcl_pipe

       不對客戶端進行檢查或作出任何操做,而是在客戶端與後端服務器之間創建專業「通道」,並直接將數據在兩者之間進行傳送:此時,keep-alive鏈接中後續傳送的數據也都將在經過此管道進行直接傳送,並不會出如今任何日誌中,經過return()返回給varnish的操做指令有:  

         error code [reson]:返回指定的錯誤代碼給客戶端並丟棄此請求,「code」是錯誤標識,例如200、405等,「reason」是錯誤提示信息。

        pipe:不對客戶端進行檢查或作出任何操做,而是在客戶端與後端服務器之間創建專業「通道」,並直接將數據在兩者之間進行傳送:此時,keep-alive鏈接中後續傳送的數據也都將在經過此管道進行直接傳送,並不會出如今任何日誌中

10.lookup

      表示在緩存裏查找被請求的對象,而且根據查找的數據把控制權交給vcl_miss或vcl_hit

11.vcl_hit

       在執行lookup指令後,若是在緩存中找到請求的內容,將自動調用此函數,經過return()返回給varnish的操做指令有:

        deliver:緩存此對象,並將其發送給客戶端(經由vcl_deliver)

        error code [reson]:返回指定的錯誤代碼給客戶端並丟棄此請求,「code」是錯誤標識,例如200、405等,「reason」是錯誤提示信息。

         pass:繞過緩存,即不從緩存中查詢內容或不將內容存儲至緩存中;

12.vcl_miss函數

      在執行lookup指令後,若是在緩存中找不到請求的內容,將自動調用此函數,此函數能夠判斷是否在後端服務器上獲取內容,經過return()返回給varnish的操做指令有:

         error code [reson]:返回指定的錯誤代碼給客戶端並丟棄此請求,「code」是錯誤標識,例如200、405等,「reason」是錯誤提示信息。

         pass:繞過緩存,即不從緩存中查詢內容或不將內容存儲至緩存中;

13.VCL處理流程圖

       經過上面對VCL函數的介紹,你們應該對每一個函數實現的功能有一個瞭解,,起始每一個函數之間是有聯繫的,以下圖所示

wKioL1cVu3LCOv4kAAFmr2HtAaw854.jpg 


狀態引擎:

1:vcl_recv    2:vcl_pipe   3:vcl_pass   4:vcl_hash    5:vcl_hit   6:vcl_miss   7:vcl_fetch   8:vcl_delier  

9:vcl_error


緩存的處理步驟:

   接受請求---解析請求---查詢緩存---新鮮度檢查---建立響應報文---發送響應---記錄日誌

 

緩存的新鮮度檢測方法:

  (1)過時時間:

         HTTP/1.0   

             Expires:"Mon, 21 Mar 2016 05:02:19 GMT"   固定時間來檢測

                    HTTP/1.1

             Cache-Control:"max-age=900"  這種最多存活時時間來檢測

 

  (2)有效性再驗證:revalidate

          若是原始內容發生改變,就正常響應,響應碼200 

          若是原始內容沒改變,則僅相應首部(不帶body部分),相應碼304Not Modified

          若是原始內容消失,響應爲404,些時緩存中cache object 也應該被刪除

   

   (3)條件式請求首部:

 

            根據時間戳判斷:

     If-Modified-Since: 自從請求的時間以後,請求的資源是否發生過修改,用時間戳驗證

     If-Unmodified-Since:自從請求的時間以後,請求的資源是否發沒有修改

      

      根據標籤來判斷:

     If-None-Match :本地緩存中存儲的文檔的Etag標籤是否與服務器文檔的Etag不匹配。

     If-Match :本地緩存中存儲的文檔的Etag標籤是否與服務器文檔的Etag匹配。

 

yum 安裝 varnish

# yum insatll varnish-libs-3.0.4-1.el6.x86_64.rpm varnish-3.0.4-1.el6.x86_64.rpm 

 wget http://repo.varnish-cache.org/redhat/varnish-3.0/el6/x86_64/varnish/varnish-3.0.5-1.el6.x86_64.rpm 

wget http://repo.varnish-cache.org/redhat/varnish-3.0/el6/x86_64/varnish/varnish-libs-3.0.5-1.el6.x86_64.rpm

wget http://repo.varnish-cache.org/redhat/varnish-3.0/el6/x86_64/varnish/varnish-docs-3.0.5-1.el6.x86_64.rpm

1:

# vi /etc/sysconfig/varnish

修改一下參數
VARNISH_LISTEN_PORT=80                     //表示將varnish對外的監聽端口改成80

 VARNISH_STORAGE="malloc,100M"             //將數據緩存在內存中,內存大小爲100M

其他的使用默認便可


2:

置varnish

     本處使用varnishadm命令行接口來刷新varnish

      命令格式:varnishadm [-n ident] [-t timeout] [-S secretfile] -T [address]:port command [...]

      經過命令行的方式鏈接至varnishd進行管理操做的工具,指定要鏈接的varnish實例有兩種方法:

       -T [address]:port 來接指定套接字上的實例

       -n ident 鏈接指定名稱的實例

    其運行模式有兩種,當不在命令行中給出指定要指定的「command」時,要將進入交互模式,不然,varnish將指定指定的「command」並退出。


# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082

 varnishadm 使用:

   vcl.load

   vcl.use

   vcl.show

   vcl.discard


varnish 通常只對 get head 緩存


backend storage:支持緩存存儲內型有3種

         -s type 

        malloc  [,size]   //內存中緩存

    file[,path[,size[,granularity]]]         //一個文件保存全部緩存

    persistent,path,size {experimental}      // 在具體生並環境中不建議用,

 

varnishl 裏可用單分支和多分支判斷

 

varnish 裏可用變量:

 1:經常使用變量,在任何引擎中均可以用的,

    new           // 獲取當前系統的當前時間

   .host          //後端主機的ip

   .port         //後斷主機的端口

 

2:用於處理請求階段

   client.ip                 // 客戶機ip

   server.hostname      // 服務器主機名(varnish服務器名)

   server.ip              // 務器主ip   (varnish ip)

   server.port         //服務器端口    (varnish 端口)

 

   req.request    //請求方法

   req.url           // 請求url

   req.porto        //請求協議

   req.backend       //用於服務這次請求的後端主機

   req.backend.healthy   //後端健康狀態

   req.http.HEADER    //引用請求報文中指定的首部

   req.hash-always_miss 

   req.hash-ignore_busy

   req.can_gzip      //客戶端是否能接受gzip 壓縮的內容

   req.restarts     //此請求被重啓的請求

 

3: varnish本身 向backend 主機發起請求前可用的變量

   bereq.request    //varnish 對後端口請求方法

   bereq.url            //varnish 對後端口請求url

   bereq.proto       //varnish 對後端請求協議

   bereq.http.HEADER    //varnish 對後端口請求頭

   bereq.connect_timeout     //等待與backend主機發起的鏈接超時時長

 

   4:backend主機的響應報文到達varnish主機後,將其放放置於cache中以前可用的變量。

   beresp.do_stream    // 流式響應

   beresp.do_gzip        //  是否壓縮後存入cache

   beresp.do_gunzip    //   是否解壓後存入緩存。

   beresp.http.HEADER   // 響應時頭

   beresp.proto             // 響應時協議

   beresp.status           //  響應狀態碼

   beresp.response        // 響應時的緣由短語

   beresp.ttl                  // 響應對象的剩餘生存時長,單位爲秒

   beresp.backend.name   // 相應報文來源的backend名稱

   beresp.backend.ip        //   響應時報文來源的backend IP

   beresp.backend.port    //   響應時報文來源的backend 端口

   beresp.storage            //響應的存儲後端

  

  5:緩存對象存入的ccache以後可用的變量

obj,proto           //響應時協議

obj.status        // 響應時狀態碼

obj.response  

obj.hits           //響應時次數

obj.ttl  

obj,http,HEADER    // 響應首部

 

  6:在決定對請求鍵作hash計算時可用的變量

     req.hash

     

  7:在爲客戶端準備響應時報文可用變量

   resp.proto

   resp.status

   resp.response

   resp.http.HEADER

 

狀態引擎:

  vcl_init: 在裝載vcl,用其處理請求以前

  vcl_recv: 請求被接入,但在其分析,處理完成以前。

             是否服務些請求,如何服務,使用那個後端主機服務

  vcl_fetch:從後端口主機收到相應報文以前被調用

      deliver

              error code 給個錯誤碼

             restart 重啓請求

       



 

warnish param的查看和修改:

varnish> param.show -l

修改連接池一些值,可是這種方法只對當前有效果

varnish> param.set thread_pool_max 4000      修改線程池個數

200 

 

varnish 線程模型:

 cache-worker 線程

 cache-mian 線程:些線程只有一個,用來啓動cache

 ban luker:

 acceptor:

 epoll: 線程池管理

 expire: 清理過時緩存

 

 

thread_pool_add_delay       2 [milliseconds]

thread_pool_add_threshold   2 [requests]

thread_pool_fail_delay      200 [milliseconds]

thread_pool_max             3000 [threads] 單個線程池啓動最多線程個數

thread_pool_min             50 [threads]

thread_pool_purge_delay     1000 [milliseconds]  每一秒清理一次緩存,請保留默認

thread_pool_stack           unlimited [bytes]

thread_pool_timeout         120 [seconds]  線程池的超時時間,

thread_pool_workspace       65536 [bytes]  線程池默認使用多少內存,建議默認

thread_pools                2 [pools]     線程池管理

thread_stats_rate           10 [requests]

 

 

varnish的命令行工具:

(1)varnishadm

(2)varnishtop:內存日誌區域查看工具

  RxHeader User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebK

it/53

  RxHeader:爲tag,基於標籤過慮,可用-i-x 選項,

  User-Agent 爲起始內容。稱爲日誌消息。用-I-X過濾

-I regexp:僅顯示被模式匹配到的條目

-X regexp:僅顯示不被模式匹配到的條目

-C:忽略大小寫

-d:顯示已有日誌

 

(3)varnishstat  緩存統計

-l 列出全部字段

-f 統計字段  -f後接的字段名

-x:xml輸出格式

-j:json 格式輸出

 

配置文件:

sub vcl_deliver {

     if (obj.hits>0) {

       set resp.http.X-Cache = "HIT";

     } else {

       set resp.http.X-Cache = "MISS";

     }

     return (deliver);

 }

下面爲varnish 配置樣本

backend default {

  .host = "192.168.1.105";

  .port = "80";

}

acl purgers {

        "127.0.0.1";

        "192.168.1.0"/24;

}

# Below is a commented-out copy of the default VCL logic.  If you

# redefine any of these subroutines, the built-in logic will be

# appended to your code.

 sub vcl_recv {

     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 == "PURGE") {

                if (!client.ip ~ purgers) {

                        error 405 "Method not allowed";

                }

                return (lookup);

        }

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

       req.request != "HEAD" &&

       req.request != "PUT" &&

       req.request != "POST" &&

       req.request != "TRACE" &&

       req.request != "OPTIONS" &&

       req.request != "DELETE" &&

       req.request != "PURGE") {

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

         return (pipe);

     }

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

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

         return (pass);

     }

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

  #       /* Not cacheable by default */

         return (pass);

     }

     return (lookup);

 }


# sub vcl_pipe {

#     # Note that only the first request to the backend will have

#     # X-Forwarded-For set.  If you use X-Forwarded-For and want to

#     # have it set for all requests, make sure to have:

#     # set bereq.http.connection = "close";

#     # here.  It is not set by default as it might break some broken web

#     # applications, like IIS with NTLM authentication.

#     return (pipe);

# }

 sub vcl_pass {

     if (req.request == "PURGE") {

                error 502 "PURGE on a passed object";

        }

     return (pass);

 }

# sub vcl_hash {

#     hash_data(req.url);

#     if (req.http.host) {

#         hash_data(req.http.host);

#     } else {

#         hash_data(server.ip);

#     }

#     return (hash);

# }

 sub vcl_hit {

     if (req.request == "PURGE") {

                purge;

                error 200 "Purged";

        }

     return (deliver);

 }


 sub vcl_miss {

     if (req.request == "PURGE") {

                purge;

                error 404 "Not in cache";

        }

     return (fetch);

 }


# sub vcl_fetch {

#     if (beresp.ttl <= 0s ||

#         beresp.http.Set-Cookie ||

#         beresp.http.Vary == "*") {

#               /*

#                * Mark as "Hit-For-Pass" for the next 2 minutes

#                */

#               set beresp.ttl = 120 s;

#               return (hit_for_pass);

#     }

#     return (deliver);

# }

 sub vcl_deliver {

     if (obj.hits>0) {

       set resp.http.X-Cache = "HIT";

     } else {

       set resp.http.X-Cache = "MISS";

     }

     return (deliver);


 }


# sub vcl_error {

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

#     set obj.http.Retry-After = "5";

#     synthetic {"

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

# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

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

# <html>

#   <head>

#     <title>"} + obj.status + " " + obj.response + {"</title>

#   </head>

#   <body>

#     <h1>Error "} + obj.status + " " + obj.response + {"</h1>

#     <p>"} + obj.response + {"</p>

#     <h3>Guru Meditation:</h3>

#     <p>XID: "} + req.xid + {"</p>

#     <hr>

#     <p>Varnish cache server</p>

#   </body>

# </html>

# "};

#     return (deliver);

# }

# sub vcl_init {

#       return (ok);

# }

# sub vcl_fini {

#       return (ok);


配置範例2:


probe chk {

  .url = "/test.html";

  .window = 5;

  .threshold = 3;

  .interval = 3s;

  .timeout = 1s;

  }

backend web1 {

  .host = "192.168.1.104";

  .port = "80";

  .probe = chk;

}

backend web2 {

  .host = "192.168.1.105";

  .port = "80";

  .probe = chk;

}


director webservers random {

  .retries = 5;

  {

    .backend = web1;

    .weight = 1;

  }


   {

    .backend = web2;

    .weight = 1;

  }

}

acl purgers {

        "127.0.0.1";

        "192.168.1.0"/24;

}

# Below is a commented-out copy of the default VCL logic.  If you

# redefine any of these subroutines, the built-in logic will be

# appended to your code.

 sub vcl_recv {

     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 ~ "test.html") {

        set req.backend = web1;

        } else {

        set req.backend = webservers;

        }

     if (req.request == "PURGE") {

                if (!client.ip ~ purgers) {

                        error 405 "Method not allowed";

                }

                return (lookup);

        }

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

       req.request != "HEAD" &&

       req.request != "PUT" &&

       req.request != "POST" &&

       req.request != "TRACE" &&

       req.request != "OPTIONS" &&

       req.request != "DELETE" &&

       req.request != "PURGE") {

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

         return (pipe);

     }

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

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

         return (pass);

     }

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

  #       /* Not cacheable by default */

         return (pass);

     }

     return (lookup);

 }


# sub vcl_pipe {

#     # Note that only the first request to the backend will have

#     # X-Forwarded-For set.  If you use X-Forwarded-For and want to

#     # have it set for all requests, make sure to have:

#     # set bereq.http.connection = "close";

#     # here.  It is not set by default as it might break some broken web

#     # applications, like IIS with NTLM authentication.

#     return (pipe);

# }

 sub vcl_pass {

     if (req.request == "PURGE") {

                error 502 "PURGE on a passed object";

        }

     return (pass);

 }

# sub vcl_hash {

#     hash_data(req.url);

#     if (req.http.host) {

#         hash_data(req.http.host);

#     } else {

#         hash_data(server.ip);

#     }

#     return (hash);

# }

 sub vcl_hit {

     if (req.request == "PURGE") {

                purge;

                error 200 "Purged";

        }

     return (deliver);

 }


 sub vcl_miss {

     if (req.request == "PURGE") {

                purge;

                error 404 "Not in cache";

        }

     return (fetch);

 }


# sub vcl_fetch {

#     if (beresp.ttl <= 0s ||

#         beresp.http.Set-Cookie ||

#         beresp.http.Vary == "*") {

#               /*

#                * Mark as "Hit-For-Pass" for the next 2 minutes

#                */

#               set beresp.ttl = 120 s;

#               return (hit_for_pass);

#     }

#     return (deliver);

# }

 sub vcl_deliver {

     if (obj.hits>0) {

       set resp.http.X-Cache = "HIT";

     } else {

       set resp.http.X-Cache = "MISS";

     }

     return (deliver);


 }


# sub vcl_error {

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

#     set obj.http.Retry-After = "5";

#     synthetic {"

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

# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

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

# <html>

#   <head>

#     <title>"} + obj.status + " " + obj.response + {"</title>

#   </head>

#   <body>

#     <h1>Error "} + obj.status + " " + obj.response + {"</h1>

#     <p>"} + obj.response + {"</p>

#     <h3>Guru Meditation:</h3>

#     <p>XID: "} + req.xid + {"</p>

#     <hr>

#     <p>Varnish cache server</p>

#   </body>

# </html>

# "};

#     return (deliver);

# }

# sub vcl_init {

#       return (ok);

# }

# sub vcl_fini {

#       return (ok);

# }

相關文章
相關標籤/搜索