varnish詳解

   

    varnish


        簡介 | 安裝 | 工作流程 | VCL介紹 | 日誌系統



簡介:

    varnish是一個web應用加速器也稱爲cache型的http反向代理,與傳統的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等諸多優點,除了它的性能,配置語言VCL使得它可以非常靈活,VCL可以讓我們編寫請求和響應的處理策略,策略可以決定提供什麼服務、從哪獲取內容以及請求和響應報頭怎樣修改。


特點:


    • 重啓後緩存數據失效;

    • 利用虛擬內存方式,I/O 性能好;

    • VCL 配置管理比較靈活;

    • 具有強大的管理功能,top、stat、admin、list 等;

    • 狀態機設計巧妙,結構清晰;

    • 利用二叉堆管理緩存文件,達到積極刪除目的。


下載安裝:    CentOS6.8    varnish-4.0.3-1.el6.x86_64


     CentOS上配置好epel源可直接yum安裝:

]# yum isntall varnish

    若想下載較新版本可從官方網站找到yum源:

    http://varnish-cache.org/releases/install_redhat.html#install-redhat


      安裝後主要文件及命令:

        主配置文件:

            /etc/sysconfig/varnish  配置varnish工作特性,監聽的地址和端口,緩存機制等;

            /etc/varnish/default.vcl 各Child/Cache線程的工作屬性,緩存策略配置

        主程序:

            /usr/sbin/varnishd

        CLI命令行接口:

            /usr/bin/varnishadm

        Shared Memory Log交互工具:

            /usr/bin/varnishhist

            /usr/bin/varnishlog

            /usr/bin/varnishncsa

            /usr/bin/varnishstat

            /usr/bin/varnishtop

        測試工具程序:

            /usr/bin/varnishtest

        VCL配置文件重載程序:

            /usr/sbin/varnish_reload_vcl

        服務啓動腳本:

            /etc/rc.d/init.d/varnish

    啓動varnish:

        ]# varnishd -f /etc/varnishd/default.vcl -s file,/var/varnish_cache,1G\

            -T 127.0.0.0:6081 -a 0.0.0.0:80

        各選項解釋:

        -f 指定 varnish 的配置文件位置

        -s 指定 varnish 緩存存儲機制,下面有解釋

        -T address:port 設定 varnish 的管理地址及其端口,用於 varnishadm 管理

        -a address:port 接收請求的地址及端口,緩存的後方應用爲 http 則可將端口設爲 80


     注: 一般 varnish 的啓動選項定義在 /etc/sysconfig/varnish 文件中,以各變量的值作爲運行參數,當使用 service varnish start 方式啓動服務時會自動加載該文件,文件內容較爲容易理解,需注意最後的 # DAEMON_OPTS="" 該變量可添加啓動時的額外選項,如:

DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300" 

以指定最大空閒線程數、最大線程數、線程超時時長等。


...

# # DAEMON_OPTS is used by the init script.  If you add or remove options, make
# # sure you update this section, too.
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
             -f ${VARNISH_VCL_CONF} \
             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
             -t ${VARNISH_TTL} \
             -p thread_pool_min=${VARNISH_MIN_THREADS} \
             -p thread_pool_max=${VARNISH_MAX_THREADS} \
             -p thread_pool_timeout=${VARNISH_THREAD_TIMEOUT} \
             -u varnish -g varnish \
             -S ${VARNISH_SECRET_FILE} \
             -s ${VARNISH_STORAGE}"
#
## Alternative 4, Do It Yourself. See varnishd(1) for more information.
#
# DAEMON_OPTS=""


varnish的緩存存儲機制( Storage Types):


    • malloc[,size]

 內存存儲,使用malloc()庫調用在varnish啓動時向操作系統申請指定大小的內存空間以存儲緩存對象;可能會產生內存碎片,影響性能


    • file[,path[,size[,granularity]]]

 文件存儲,黑盒,使用特定單個文件存儲全部的緩存數據,並通過操作系統的mmap()系統調用將整個緩存文件映射至內存區域,重啓後所有緩存項失效;


    • persistent,path,size

     與file功能相同,黑盒,但可以持久存儲數據;目前測試階段;


可在/etc/sysconfig/varnish文件中定義VARNISH_STORAGE=;或varnishd -s TYPE


Varnish無法追蹤某緩存對象是否存入了緩存文件,從而也就無從得知磁盤上的緩存文件是否可用,因此,file存儲方法在varnish停止或重啓時會清除數據。



設計結構:


wKioL1gj4tKTMxvLAAEiS2HkXV4825.png



工作流程:


     Varnish 與一般服務器軟件類似,分爲 master 進程和 child 進程。Master 進程讀入存儲配置文件,調用合適的存儲類型,然後創建 / 讀入相應大小的緩存文件,接着 master 初始化管理該存儲空間的結構體,然後 fork 並監控 child 進程。Child 進程分配若干線程進行工作,主要包括一些管理線程和很多 worker 線程。

      Varnish 的某個負責接收新 HTTP 連接線程開始等待用戶,如果有新的 HTTP 連接過來,它總負責接收,然後喚醒某個等待中的線程,並把具體的處理過程交給它。Worker 線程讀入 HTTP 請求的 URI,查找已有的 object,如果命中則直接返回並回複用戶。如果沒有命中,則需要將所請求的內容,從後端服務器中取過來,存到緩存中,然後再回復。具體決策操作流程由vcl各狀態引擎實現


wKiom1gkCPmyZBZfAAHjV-ZN_mo736.png-wh_50


配置Varnish


VCL簡介:

    VCL(varnish configuration language)是 varnish 域專用的配置語言,用來描述請求處理過程、定義數據的存儲策略。VCL 語法比較簡單,和 C 和 Perl 比較相似。當新的配置被加載時,主控進程會啓用vcc將配置文件編譯成二進制程序(所以依賴到 gcc 環境),並組織成共享對象(Shared Object)交由Child進程加載使用,若編譯失敗會返回相應錯誤,varnish運行時可隨時加載配置文件。


想要配置varnish正常工作。需先了解varnish 的配置語言VCL,“域專用”指的是有些數據僅出現於特定的狀態中。

    • VCL文件以 vcl 4.0 爲起始;    /etc/varnish/default.vcl

    • //,#,/*..*/ 爲註釋

    • sub定義一個subroutings

    • 沒有循環,有限狀態

    • 以一個關鍵詞作爲返回狀態參數以表示下一步動作,即:return(action)

    • 域專用的配置語言

    • 操作符:=、==、~、!、&&、||、<、>=


示例:    該爲varnish默認策略中的一段,表示若請求方法爲GET、HEAD則直接交由後端主機處理

        若請求包含認證或Cookie則直接交由後端主機處理

sub vcl_recv {
    ...
    if (req.method != "GET" && req.method != "HEAD") {
        /* We only deal with GET and HEAD by default */
        return (pass);
    }
    if (req.http.Authorization || req.http.Cookie) {
        /* Not cacheable by default */
        return (pass);
    }
    ...
}


vcl state engine 狀態引擎:

vcl_recv:用於接收和處理請求;當請求到達併成功接收後被調用,通過判斷請求的數據來決定如何處理請求;

vcl_pipe:用於將請求直接傳遞至後端主機,並將後端響應原樣返回客戶端;

vcl_pass:用於將請求直接傳遞至後端主機,但後端主機的響應並不緩存直接返回客戶端;

vcl_hit:在執行 lookup 指令後,在緩存中找到請求的內容後將自動調用該函數;

vcl_miss:在執行 lookup 指令後,在緩存中沒有找到請求的內容時自動調用該方法,此函數可用於判斷是否需要從後端服務器獲取內容;

vcl_hash:在vcl_recv調用後爲請求創建一個hash值時,調用此函數;此hash值將作爲varnish中搜索緩存對象的key;

vcl_purge:pruge操作執行後調用此函數,可用於構建一個響應;

vcl_deliver:將在緩存中找到請求的內容發送給客戶端前調用此方法;

vcl_backend_fetch:向後端主機發送請求前,調用此函數,可修改發往後端的請求;

vcl_backend_response:獲得後端主機的響應後,可調用此函數;

vcl_backend_error:當從後端主機獲取源文件失敗時,調用此函數;

vcl_init:VCL加載時調用此函數,經常用於初始化varnish模塊(VMODs)

vcl_fini:當所有請求都離開當前VCL,且當前VCL被棄用時,調用此函數,經常用於清理varnish模塊;

vcl_synth:自定義返回頁面,可在purge操作時調用。


主要語法:


sub subroutine {
...
}
if CONDITION {
...
} else {
...
}
return(), hash_data()


配置示例:


  

]# vi /etc/varnish/default.vcl

]# varnish_reload_vcl



後端主機健康監測:

probe check {        定義該檢查的名稱爲 check ,當後端主機較多時,直接在 backend 中調用即可。
    .url = "/.healthcheck.html";
    .window = 5;    基於最近多少次探測
    .threshold = 4;  最近.window定義的檢查次數中.threshhold定義的次數成功則爲健康
    .interval = 2s;    檢查時間間隔
    .timeout = 1s;     超時時長
    .expected_response:  期望的響應碼,默認爲200;
}


聲明並初始化一個後端對象:

backend web1 { 
   .host = "10.1.235.33"; 
   .port = "80"; 
   .probe = check;    調用該檢查機制
}
backend web2 { 
   .host = "10.1.235.66"; 
   .port = "80"; 
   .probe = check;
}


清除圖片類請求響應首部cookie字段,取消私有標識,並指定可緩存時長ttl (增加)

sub vcl_backend_response {
    if (bereq.http.cache-control !~ "s-maxage") {
        if (bereq.url ~ "(?i)\.jpg$") {        (?i) 表示不區分大小寫
            set beresp.ttl = 7200s;
        unset beresp.http.Set-Cookie;
    }
        if (bereq.url ~ "(?i)\css&") {
            set beresp.ttl = 7200s;
            unset beresp.http.Set-Cookie;
        }
    }
}


緩存對象修剪:

purge 自定義的方法,通常請求指定url緩存

ban 通常用來清理表達式匹配的緩存項

acl purge {acl控制,定義可清理緩存的主機地址,防止用戶操作
"localhost";
"10.1.235.6"/16;
}
sub vcl_recv {
if (req.method == "PURGE") {     若方法爲 PURGE 則執行清理操作
if (!client.ip ~ purge) {    限制來源
return(synth(405,"Not allowed."));
}
    return (purge);    定義下一步
}
}
sub vcl_purge {
return (synth(200,"Purged."));    返回 sycth 定義的頁面
}


當有多個backend:動靜分離

設定多個後端主機

backend default {
.host = "10.1.235.66";
.port = "80"
}
backend phpsrv {
.host = "10.1.235.77";
.port = "80";
}


接收時策略,對不同類型的資源請求分發到專用的後端服務器上

vcl_recv {
   if (req.url ~ "(?i)\.php$") {
       set req.backend_hint = "phpsrv";
   } else {
       set req.backend_hint = "default";
   }
}


實現負載均衡: 緩存可能導致無負載均衡效果,可定義不可緩存文件或目錄測試


import directors;    # 需先加載 directors

定義後端主機:

backend web1 {
   .host = "10.1.235.33";
}
backend web2 {
   .host = "10.1.235.66";
}


定義後端服務器組:

sub vcl_init {
   new websrv = directors.round_robin();    round_robin|random 調度算法較少
   websrv.add_backend(web1);
   websrv.add_backend(web2);
}


分發請求時調用該組:

sub vcl_recv {
   # send all traffic to the bar director:
   set req.backend_hint = websrv.backend();
}



日誌系統:


    varnish 默認將日誌記錄在一段共享內存中 shared memory log ,內存空間分爲兩部分,計數器和日誌信息,提供非常詳細的信息,這提高了性能,但不易於查找問題,記錄在內存中的數據無法長時間保存。

    內存中日誌區域大小有限,如果不使用一個程序將日誌信息保存到磁盤上,日誌數據將會被不斷覆蓋。


日誌查看命令:


]# varnishlog    動態持續更新顯示日誌信息


]# varnishtop    對日誌信息做了整理排序

-1 僅輸出一次靜態信息後退出    數字 1

-i taglist,可以同時使用多個-i選項,也可以一個選項跟上多個標籤;

-I <[taglist:]regex>

-x taglist:排除列表

-X <[taglist:]regex>


]# varnishstat    緩存狀態查看

-1 -f FILED_NAME 

-l:可用於-f選項指定的字段名稱列表;


日誌記錄服務:

varnishlog    以varnishlog命令輸出的格式記錄日記,內容較多,不易讀

varnishncsa    以類似http訪問日誌格式記錄日誌,combined 日誌格式


一般可開啓 varnishncsa 服務將日誌記錄於磁盤上

]# service varnishncsa start

    默認保存於 /var/log/varnish/varnishncsa.log





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章