varnish原理及配置事例

Varnish是一款高性能的開源HTTP加速器(其實就是帶緩存的反向代理服務),可以把http響應內容緩存到內存或文件中,從而提高web服務器響應速度。與傳統的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等諸多優點,很多大型的網站都開始嘗試使用 varnish 來替換 squid,這些都促進 varnish 迅速發展起來

Varnish程序結構

wKiom1WdOjjQ8WCbAAFUjsrr5iY407.jpg

clip_image002

管理進程:編譯VCL并應用新配置、監控varnish、初始化varnish,并提供一個CLI,初始化緩存的內存結構,對緩存內存結構實現分成各個類型大小的內存塊。

Child/Cache線程有幾類:

    Acceptor:接收新的連接請求;

    Worker:用于處理并響應用戶請求;

    Expiry:從緩存中清理過期cache object

 

日志:Shared Memory Log,  共享內存內存日志大小一般90MB;分為兩部分:前一部分為計數器、后一部分為客戶請求相關的數據。

對varnish內的緩存數據的有效管理:

                Expires:定義一個緩存時長,過了緩存時長就認為緩存失效。

                http validation

If-Modified-Since/Last Modified : 每次客戶端請求緩存內容,varnish會向后端主機詢問這個緩存對象自它緩存的時間開始時有沒有改變,沒改變的話會返回一個304,證明可以返回varnish內的緩存內容,如果改變了,需要向后端請求該內容返回給客戶端。

                        If-None-Match/Etag:會對varnish的緩存內容一個標簽和一個緩存時間,過了這個時間,向后端主機詢問這個緩存內容的標簽是否有改變,沒改變的話這個緩存內容增加其緩存時間。


Vcl內置函數和處理流程(狀態引擎)

wKiom1WdOjrS1nfvAAHj5JDxUZ4356.jpg

Vcl內置函數:vcl配置的緩存策略在此些內置函數發揮作用;

vcl_recv:用于接受和處理請求。當請求到達并成功接收后被調用,通過判斷請求的數據來決定如何處理請求。例如如何響應、怎么響應、使用哪個后端服務器等。

vcl_fetch:根據服務器端的響應作出緩存決策,如判斷獲取的內容來決定是將內容放入緩存,還是直接返回給客戶端。

vcl_pipe:對于無法理解的用戶請求,將請求直接發往后端主機;

vcl_hash:自定義hash生成時的數據來源

vcl_pass:用于將請求直接傳遞至后端主機,后端主機在應答數據后將應答數據發送給客戶端,但不進行任何緩存。

vcl_hit:從緩存中查找到緩存對象時要執行的操作;

vcl_miss:從緩存中款查找到緩存對象時要執行的操作;

vcl_deliver:將用戶請求的內容響應給客戶端時用到的方法;

vcl_error:在varnish端合成錯誤響應而時;

vcl的配置語法:

    (1) //, #, /*comment*/用于注釋;

    (2) sub $NAME 用于定義函數;

    (3) 不支持循環;

    (4) 有眾多內置變量;

    (5) 支持終止語句,沒有返回值;

    (6) “域”專用語言;

    (7) 操作符: =, ==, ~, !, &&, ||

 

wKiom1WdOjrS1nfvAAHj5JDxUZ4356.jpg

            

常用變量:

    1、在任何引擎中均可使用:

        Now:獲取當前系統當前時間

.host:獲取當前主機名和ip地址

.port:后端服務器名稱和端口

 

    2、用于處理請求階段:

        client.ip,server.hostname, server.ip, server.port :都不解釋

        req.request:請求方法

        req.url:請求的URL

        req.proto:HTTP協議版本

        req.backend:用于服務此次請求的后端主機;

        req.backend.healthy:后端主機健康狀態;

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

        req.can_gzip:客戶端是否能夠接受gzip壓縮格式的響應內容;

        req.restarts:此請求被重啟的次數;

 

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

        bereq.request:請求方法

        bereq.url:請求url

        bereq.proto:HTTP協議版本

        bereq.http.HEADER:調用服務此次請求的后端主機的報文首部

        bereq.connect_timeout:等待與beckend建立連接的超時時長

 

    4、backend主機的響應報文到達本主機(varnish)后,將其放置于cache中之前可用的變量

        beresp.do_stream:流式響應(接收一個請求,響應一個請求)

        beresp.do_gzip:是否壓縮之后再存入緩存;

        beresp.do_gunzip:如果從后端收到壓縮格式的報文,是否解壓縮在存放下來

        beresp.http.HEADER:獲取httpd的首部信息

        beresp.proto:HTTP協議版本

        beresp.status:響應狀態碼

        beresp.response:響應時的原因短語

        beresp.ttl:響應對象剩余的生存時長,單位為秒鐘;

        beresp.backend.name:此響應報文來源backend名稱;

        beresp.backend.ip:獲取后端響應ip

        beresp.backend.port:獲取后端響應端口

        beresp.storage:強制varnish將緩存存儲到緩存后端

 

    5、緩存對象存入cache之后可用的變量

        obj.proto:響應時使用的協議

        obj.status:響應時使用的狀態碼

        obj.response:服務器返回響應報文的狀態碼

        obj.ttl:緩存對象生存時長

        obj.hits:緩存對象被用作響應時的次數

        obj.http.HEADER:調用對應的響應報文

 

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

        req.hash:指明把什么作為hash的鍵,作為緩存的鍵

 

    7、在為客戶端準備響應報文時可用的變量

        resp.proto:指明使用什么協議響應

        resp.status:執行響應狀態嗎

        resp.response:返回響應的狀態碼

        resp.http.HEADER:調用響應報文狀態碼

變量在各狀態引擎使用情況:

wKiom1WdOkLQKbelAAF0SUqSJgU337.jpg

varnish配置實例:

/etc/sysconfig/varnish 是定義varnish運行特性的配置文件;

/etc/varnish/default.vcl 是定義varnish的默認狀態引擎的工作配置文件(使用vcl語言定義)

(1)定義varnish后端多主機的實例:

        backend bs1 {

        .host = "www2.bwei.com";

        .port = "80";

}

 

 

backend bs2 {

        .host = "www3.bwei.com";

        .port = "80";

}

 

director bs random {

{ .backend = bs1; .weight=1; }

{ .backend = bs2; .weight=2; }

}

 

sub vcl_recv {

        if (req.url ~ "index.html"){

        set req.backend = bs;

}

}

這里的director是實現調度器的角色,實現把兩個后端server合在一起,配置他們的權值及后端server的調度方式,這里有一重點,我們定義了后端server要在vcl_recv這個函數中調用,即定義那個資源要調配到那個后端server上。

(2)實現給客戶端的響應報文中,增加一個首部,給用戶看是否緩存命中。

sub vcl_deliver{

            if (obj.hit >0){

            set resp.http.X-cache = "hit via"+" "+server.hostname;

}else{

            set resp.http.X-cache = "miss via"+" "+server.hostname;

}

}

(3)實現讓某些主機可以刪除varnish主機上的緩存:

acl purgers {

                127.0.0.1;

                192.168.179.0; /24

}

sub vcl_recv{

            if (client.ip !~ purgers && req.request == "PURGE"){

            error 405 "method not allowed";            

}

            return (lookup);

}


sub vcl_hit{

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

                purge;

                error 200 "cache has purge";

}

}


sub vcl_miss{

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

            purge;

            error 404 "not in cache";

}

sub vcl_pass{

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

            error 502 "purge object not allowed in pass"

}

}


實現給varnish解析不了的方法,送到pipe上:

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" ){ return (pipe);

實現讓除GET,HEAD,PURGE的方法可以到達hash狀態引擎,其余到達pass引擎

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

                return (pass);

}

從后端主機獲取資源后,設定其緩存時間和不緩存cookie信息

sub vcl_fetch{

        set beresp.ttl = 15s;

        if (beresp.http.Set-Cookie){

              return (pass)

}

return (deliver);

}

從后端主機獲取資源后,設置那些不能緩存的數據不進行緩存

sub vcl_fetch{

        if(!beresp.cacheable){

            return (pass);

}

        if(beresp.http.Pragma ~"no-cache" ||

            beresp.http.Cache-Control ~ "no-cache" || 

            beresp.http.Cache-Control ~ "private"){

            return (pass);    

}

}

設置客戶端請求我們的varnish出現認證和cookie時,把它們直接送去pass引擎

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

            return (pass);

}

設置對后端主機進行健康狀態檢查:

probe healthcheck {

        .url = "/health.html";

        .interval = 60s;

        .timeout = 0.3s;

        .window = 8; 

        .threshold = 3;

        .initial = 3;

        .expected_response = 200;

}

backend bs1 {

        .host = "www2.bwei.com";

        .port = "80";

        .probe = healthcheck;

}

 

 

backend bs2 {

        .host = "www3.bwei.com";

        .port = "80";

        .probe = healthcheck;

}

varnish的配置段需要我們對其進行編譯才能運行,我們對其每次對其進行改變都需要重新編譯和使用:

        varnishadm管理軟件可以實現vcl語言編譯:vcl.load <name> <filename>(加載vcl配置)

                                                                        vcl.use <name> (使用vcl配置)

原創文章,作者:13-廣州-楊過,如若轉載,請注明出處:http://www.www58058.com/9551

(1)
13-廣州-楊過13-廣州-楊過
上一篇 2015-12-06
下一篇 2015-12-06

相關推薦

  • 網絡26期 第五周作業

    1. 顯示當前系統上root、fedora或user1用戶的默認shell egrep -o “^(root|fedora|user1)\>.*[^:]+$” /etc/passwd | cut -d: -f1,7 2. 找出/etc/rc.d/init.d/functions文件中某單詞后面跟一組小括號的行,形如:hello(…

    2017-03-13
  • 馬哥教育網絡班22期+第8周課程練習 忍者亂太郎喻成

    第八周 1、請描述網橋、集線器、二層交換機、三層交換機、路由器的功能、使用場景與區別。 一個好的鏈接,主要的參考http://www.cnblogs.com/imapla/archive/2013/03/12/2955931.html簡單的總結和自己的理解橋接器(network bridge),又稱網橋,一種網絡設備,負責網絡橋接(network …

    Linux干貨 2016-12-26
  • 談shell命令的神奇組合以及對腳本的影響

    shell命令是我們與機器交互的基本溝通翻譯官。我們要告訴計算機的很多事情都由它來翻譯,而shell的神奇之處就在于支持命令聯合使用,現在我就來講講基本的命令組合引用。1.管道應用:命令 | 命令  ,前面的命令的結果可以直接作為后面命令的輸出,省卻了一個變量做存儲。2.文本段落提??;我們可以用 組合命令 通常為 cat 某文件 | (head -…

    Linux干貨 2017-04-02
  • Shell腳本編程—函數

    函數:     把一段獨立功能的代碼當作一個整體,并命名一個名字;命名的代碼段,此即為函數     由若干條shell命令組成的語句塊,實現代碼重用和模式化編程 函數的作用:     在某些場景下,我們可以將獨立功能的一段代碼定義為一個函數…

    Linux干貨 2016-08-24
  • DNS

    這里都以我本機的實驗為例 正向解析:就是從主機名到IP的解析過程 先在工作目錄/var/named/創建一個區域數據文件 以zcylinux.io域為例:vim/var/named/zcylinux.io.zone $TTL  600     #設置全局變量TTL的值為600s zcylinux.io.&nb…

    Linux干貨 2017-05-30
  • raid5 陣列

    1 fdisk 分區sdb2,sdd1,sde1, 2  新建raid5 [root@localhost ~]# mdadm -C /dev/md5 -a yes  -l 5  -n 3 -x 1 /dev/sdd1 /dev/sde1  /dev/sdf  /dev/sdb2  3   …

    Linux干貨 2017-04-25

評論列表(1條)

  • stanley
    stanley 2015-12-06 20:32

    圖很專業,代碼如何能格式化配合一定樣式就是精品了

欧美性久久久久