緩存服務器memcached和varnish

兩類緩存服務器:
1.代理式緩存服務器;proxy-like cache server;
2.旁掛式緩存服務器;bypass cache server;php

緩存服務器也能夠根據緩存數據內容分類:
    1.數據緩存;data cache
    2.頁面緩存;page cache

數據存在訪問熱區,指被常常訪問的數據。css

緩存的實質是:用空間換時間;
緩存的局部性特徵:空間局部性和時間局部性:html

緩存的時效性:
過時清理:PURGE,修剪;
未過時但溢出清理:LRU(最少使用原則);
未過時但被修改:PURGE,修剪;前端

緩存命中率:Hits/(Hits + Miss) ,取值範圍區間是(0,1),一般也會用百分數進行表示;
頁面命中率:基於命中的頁面數量進行統計衡量的一種標準;
字節命中率:基於命中的頁面的體積進行統計衡量的一種標準;(更爲精確)web

數據緩存與否:
1.私有數據:private data,放置於私有緩存中;
http/1.1版本後的首部中,提供了一個Cach-Control的首部;Cache-Control首部的值中包含有private字樣,或者提供了Cookie或者Cookie2的首部;此類數據大多數都是由瀏覽器完成緩存;
2.公共數據:public data,能夠放置於公共緩存,也能夠放置於私有緩存中;
此類數據大多數緩存在反代服務器上或者專用的Cache Server上;
小部分也能夠緩存在瀏覽器上;正則表達式

注意:
    瀏覽器的緩存(通常是私有緩存):
        僅針對於單獨的用戶生效,使用戶重複訪問某資源時可以加速訪問;
    緩存服務器的緩存(通常是公共緩存):
        爲前端調度器或反代服務器加速資源訪問,下降後端資源服務器的訪問壓力;

對於緩存服務器來講,緩存的處理步驟(大體成功的處理步驟):
接收請求 --> 解析請求(從請求報文的http協議首部中提取URL及其餘相關的首部信息) --> 查詢緩存 --> 緩存數據的新鮮度檢測 --> 構建響應報文 --> 發送響應報文--> 記錄日誌算法

緩存數據的有效性判斷機制:
1.過時時間:
HTTP/1.0:
Expires,絕對時間;
HTTP/1.1:
1.Expires
2.Cache-Control(首部):max-age=86400
3.Cache-Control:s-maxage=10000 (s表明公共緩存)
2.條件式請求:
Last-Modified/If-Modified-Since :響應報文/請求報文的條件請求
Etag/If-None-Match :擴展標籤,對標籤進行哈希計算;If-None-Match:若是不匹配,返回200表明不匹配express

示例:查看百度的logo資源:
Cache-Control max-age=2592000 //緩存資源的最大有效時間
ETag "593645fd-664" //獲得的16進制的哈希值
Expires Wed, 11 Jul 2018 03:43:28 GMT //過時時間
Last-Modified Tue, 06 Jun 2017 06:04:45 GMT //自 06 Jun 2017 06:04:45 GMT這個時間點開始資源無變化(GMT:格林尼治時間)vim

1、memcached緩存服務器:
屬於旁掛式緩存服務器,也屬於數據緩存;後端

memcached存儲形式:
    1.將全部數據採用鍵值對兒的形式存儲於內存當中;
    2.無持久存儲功能;
    3.一般用於緩存小文件,小數據,單項緩存數據內容上限是1MB;

memcached由LiveJournal公司旗下的子公司Danga Interactive研發者Brad Fitzpatrick研發;

memcached特性:
    1.k/v cache;可序列化數據,扁平化數據;         //常見的還有JSON,也是序列化數據
    2.存儲項:key(鍵), value(值), flag(16位二進制數字,0-65535), expire_time(超時時間), length(保存數據的長度)等簡單部分組成;
    3.旁掛式緩存,功能實現一半依賴於客戶端,另外一半靠memcached server;
    4.O(1)的查找和執行效率;
    5.能夠構建分佈式緩存系統,各服務器之間互不通訊的分佈式集羣系統;
    6.緩存數據的處理方式(較爲特殊):
        1)緩存空間耗盡:根據LRU(最近最少使用算法)完成清理過時數據;
        2)緩存項過時:惰性清理機制---用來儘量減小內存碎片
    7.內存分配方式:
        slab allocation:按照頁面進行打散,將打散的頁面分紅若干個更小的頁面,最大1M
            facter:增加因子;默認1.25倍遞增;小頁面根據增加因子來分配空間大小,最後會留下一個最大不超過1M的空間。

安裝配置memcached:
    1.base源中有對應的rpm包;能夠直接使用yum方式安裝內容;
            ~]# yum install memcached -y
    2.從memcached.org官方站點下載源代碼包,編譯安裝;

    memcached緩存服務監聽的端口:
        11211/TCP, 11211/UDP;

    memcached緩存服務程序安裝後的默認環境:
        主程序:/usr/bin/memcached
        環境配置文件:/etc/sysconfig/memcached
            ~]# cat /etc/sysconfig/memcached 
            PORT="11211"        //監聽的端口號
            USER="memcached"    //程序屬於哪一個用戶
            MAXCONN="1024"      //服務的最大鏈接數
            CACHESIZE="64"      //緩存大小默認爲64
            OPTIONS=""                  //其餘選項默認爲空

    memcached緩存服務使用的協議是memcached協議,memcached協議支持的數據傳輸格式是:
        1.文件格式
        2.二進制格式

    交互式操做(~]# telnet+載有memcached服務主機的IP地址+端口號(默認是11211),使用telnet命令進入交互式操做模式):
        命令:
            1.統計類:stats, stats items(緩存項查看), stats slabs(內存空間的查看), stats sizes
            2.管理類:set(修改特定鍵的值), add(添加一個新的鍵), replace(替換原有鍵的值), append(在原有鍵值後附加一個值), prepend(在原有鍵值前附加一個值), delete(刪除鍵), incr(給鍵添加值), decr(給鍵刪除值), flush_all(清空全部鍵)
            3.查看類:get

        memcached交互式命令的通常格式:
            <command> key_name [flags] [expire_time] [length_bytes] \n

             key_name:鍵名
             [flags]:標誌位,範圍是0-65535
             [expire_time]:鍵最大緩存時間(秒)
             [length_bytes]:字符長度

            例:
                添加一個新鍵:
                    add testkey 0 300 11
                    hello world
                    STORED
                查看新鍵:
                    get testkey
                    VALUE testkey 0 11
                    hello world
                    END
                在新鍵後添加字符並查看:
                    添加:
                        append testkey 0 300 2
                        hi
                        STORED
                    查看:
                        get testkey
                        VALUE testkey 0 13
                        hello worldhi
                        END
                在新鍵前添加字符並查看:
                    添加:
                        prepend testkey 0 300 3
                        hi 
                        STORED
                    查看:
                        get testkey
                        VALUE testkey 0 14
                        hi hello world
                        END

    memcached命令選項:
        -c num :指名併發鏈接數量,默認是1024
        -m num :分配多大的內存空間,默認是64M
        -u username :指定哪一個用戶啓動memcached服務進程
        -p port :指定端口號,默認是11211
        -U port :指定UDP協議的端口號,默認是11211,0是關閉
        -l ipaddress :監聽哪個地址,默認是全部
        -f facter :指明增加因子,默認是1.25倍
        -t thread_num :設置線程數,默認是4個線程
        -v,-vv,-vvv :顯示的詳細信息程度

2、VARNISH緩存服務器:
varnish緩存服務器是屬於頁面緩存服務器的一種,用來爲客戶端請求提供查詢結果,也屬於代理式緩存服務器。

varnish緩存服務器特色:
    varnish緩存服務器能夠實現的功能:反向代理 + 緩存服務器
    varnish緩存服務器默認在內存中佔用128M內存空間去進行緩存服務

緩存服務器的實現:
開源解決方案:
squid:上世紀90年代中期出現;使用率較低
varnish:反向代理式緩存:使用率較高的緩存服務器實現方案;
https://www.varnish-software.com/ //商業版本服務站點
http://varnish-cache.org/ //開源站點

varnish程序的組織結構:
        1.Management進程:
                     1)varnish的主進程;
                     2)提供命令行工具的訪問接口,用來管理子進程,初始化緩存;
        2.Child/Cache進程:擁有多種線程模型,以下:
                    command line
                    storage/hashing
                    log/stats
                    accept
                    worker threads
                    object expiry
                    backend communication
                    ...
        3.VCL compiler:C compiler(gcc)

varnish的線程池做用:
    統計數據:數據統計和計數器;
    日誌區域:日誌數據;

VCL文件的處理方式:
    vcl compiler (vcl編譯器編譯完成)--> C compiler (再到C的編譯器中編譯處理)--> shared object

vcl配置文件的重載工具:
        /usr/sbin/varnish_reload_vcl

VCL:Varnish Configuration Language,varnish配置語言;
統一存放於後綴名爲".vcl"的文件中,在初次安裝了varnish以後,在配置主目錄中會自動建立出一個名爲"default.vcl"的文件,但其內容幾乎爲空;

varnish的安裝:
在EPEL源中直接提供了varnish的穩定版本;
安裝命令:yum install -y varnish (需先配置EPEL源)

varnish的程序環境:
    1.配置文件:
        /etc/varnish/default.vcl
            定義緩存策略的默認配置文件,主要用於配置各Child/Cache線程的工做屬性;
        /etc/varnish/varnish.params
            定義varnish緩存服務的運行時參數以及工做特性;
        /etc/varnish/secret
            在使用varnishadm命令行管理工具時,爲了安全起見使用的預共享密鑰;

    2.主程序:  /usr/sbin/varnishd

     1)CLI(簡單的命令行接口管理工具):
        /usr/bin/varnishadm

     2)Share Memory Log交互工具:
        /usr/bin/varnishhist
        /usr/bin/varnishlog
        /usr/bin/varnishncsa
        /usr/bin/varnishstat
        /usr/bin/varnishtop

                開啓varnish日誌記錄(默認沒有開啓):
                    1./usr/bin/varnishlog
                    2./usr/bin/varnishncsa(建議在須要開啓日誌記錄的時候開啓,由於其更接近於Apache的command的命令形式)

    3)緩存測試工具:
        /usr/bin/varnishtest

    4)varnish的Unit FIle:
        /usr/lib/systemd/system/varnish.service:管理varnish的Management進程;
        實現日誌持久化存儲的服務文件;
            /usr/lib/systemd/system/varnishlog.service
            /usr/lib/systemd/system/varnishncsa.service

主程序:/usr/sbin/varnishd
    varnishd - HTTP accelerator daemon  --http加速器守護進程
        經常使用選項:
            -a address[:port][,address[:port][...]
                指定用於接收客戶端請求所監聽的地址和服務端口,默認值爲127.0.0.1:6081
            -b host[:port]:添加一個backend sever的主機和端口號
            -T address[:port]:實現管理的時候須要用到的地址和端口號;
            -f config:
                指明這次須要編譯並裝載的VCL配置文件,默認爲/etc/varnish/default.vcl;
            -p param=value
                設置varnish線程模型的運行時參數和參數值;
                大多數的運行時參數都有默認值,不要輕易嘗試調整運行時參數的值;
                在命令行工具中使用此選項調整的運行時參數的值,僅當次生效;
            -r param[,param...]
                將運行時參數設置爲只讀屬性;意味着當再次運行時,其值沒法被修改;
            -s [name=]type[,options]:指定緩存的存儲機制
                定義緩存數據的存儲方式,目前有三種存儲機制:
                    1.malloc[,size]:性能最好,可是全部的數據保存在內存中;
                    2.file[,path[,size[,granularity]]]:只是一種黑盒文件,內容沒法觀察;鍵值對兒存放於內存當中,哈希值存放於磁盤中,保證快速檢索,不會佔用內存太多空間
                    3.persistent,path,size (experimental,體驗測試版):持久存儲(機制不成熟)

            -T address[:port]
                在指定的IP地址和端口號上提供管理接口;默認爲127.0.0.1:6082;
            -u user、-g group
                指定容許varnish服務進程的系統用戶和系統組,默認均爲varnish;

    運行時參數的配置文件:/etc/varnish/varnish.params
        DAEMON_OPTS="-p param1=value1 -p param2=value2 ..."

        thread_pool_min=5
        thread_pool_max=500
        thread_pool_timeout=300

命令行管理工具:varnishadm (交互式模式)
    varnishadm - Control a running Varnish instance
        經常使用選項:
            -S secret_file
                指定經過命令行工具實現驗證時的預共享密鑰文件;
            -T address:port
                指定管理地址和端口;

    交互式模式的命令:
        help [<command>] :varnishadm命令幫助
        ping [<timestamp>] :作連通測試
        auth <response> :作認證
        quit :退出交互式模式
        banner :作條幅
        status :狀態輸出
        start :啓動varnish服務(不建議使用)        //重啓、關閉、開啓都會把緩存清空,這是致命的
        stop :關閉varnish服務(不建議使用)
        管理vcl:
            vcl.load <configname> <filename>:裝載而且編譯vcl文件
            vcl.inline <configname> <quoted_VCLstring>:
            vcl.use <configname>:激活已經編譯好的vcl文件;
            vcl.discard <configname>:刪除已經編譯好的非激活狀態下的vcl配置文件;
            vcl.list:vcl配置文件一共有哪些;
        param.show [-l] [<param>]:列舉全部運行時參數而且輸出詳細參數;
        param.set <param> <value>:臨時修改某個運行時參數的值,一次性修改,重啓後恢復默認
        panic.show:顯示運行時參數列表或顯示指定的運行時參數的詳細信息;
        panic.clear:清空運行時參數列表;
        storage.list:顯示緩存存儲相關信息;
        vcl.show [-v] <configname> :顯示default.vcl全部配置歷史更改列表,包括正在使用和使用過的;
        backend.list [<backend_expression>] :後端服務器列表顯示;
        backend.set_health <backend_expression> <state> :設置後端服務器將康狀態碼;

經常使用的命令:
    VCL配置文件管理相關:
        vcl.load:裝載並編譯VCL配置文件;
        vcl.use:激活已經編譯完成的VCL配置文件;
        vcl.discard:刪除非激活狀態下的VCL配置文件;

    運行時參數相關:
        param.show:顯示運行時參數列表或顯示指定的運行時參數的詳細信息;
        param.set:實時設置或修改運行時參數的值;(不要輕易嘗試修改,必定要清楚操做的目的)

    緩存存儲相關:
        storage.list:顯示緩存存儲相關信息;

    後端服務器相關:
        backend.list:顯示能夠直接訪問的後端服務器列表;
        backend.set_health:指明後端服務器的健康狀態檢測方式;

VCL:Varnish Configuration Language;
    "域"專有類型的配置語言;

    VCL中定義了多個狀態引擎,各狀態引擎之間存在相關性,同時又彼此隔離;每一個狀態引擎內均可以使用return()關鍵字指明各狀態引擎之間的關聯關係;在VCL文件中,狀態引擎使用以下的方式進行定義:
        sub STATE_ENGINE_NAME { ...; }
        sub+狀態引擎的名字+{ 配置指令1;配置指令2;... }

三個varnish狀態引擎版本對比以及數據處理流程:
1.varnish 2.0-狀態引擎包括:
vcl_recv:接收請求,而且判斷是否可使用緩存數據;
vcl_hash:對於從backend端取回的數據,若是可被緩存,則進行哈希計算;
vcl_hit:對於請求的資源能夠在緩存對象中直接獲取;
vcl_miss:對於請求的資源沒法在緩存對象中直接獲取;
vcl_deliver:構建響應報文;
vcl_fetch:從backend端取回數據;

varnish2.0的處理流程:
            1.vcl_recv --> vcl_hash --> vcl_hit --> vcl_deliver
            2.vcl_recv --> vcl_hash --> vcl_miss --> vcl_fetch --> vcl_deliver
            3.vcl_recv --> vcl_fetch --> vcl_deliver (不走緩存)

    2.varnish 3.0狀態引擎包括:
        vcl_recv:接收請求,而且判斷是否可使用緩存數據;
        vcl_hash:對於從backend端取回的數據,若是可被緩存,則進行哈希計算;
        vcl_hit:對於請求的資源能夠在緩存對象中直接獲取;
        vcl_miss:對於請求的資源沒法在緩存對象中直接獲取;
        vcl_deliver:構建響應報文;
        vcl_fetch:從backend端取回數據;
        較varnish2.0新增:
            vcl_pass:對於原本能夠從緩存中查找到資源明確的設置不使用緩存;多數用於私有緩存的查找策略;
            vcl_pipe:對於沒法理解的請求,直接按照原樣的封裝直接代理至backend端;
            vcl_error:本地發生錯誤時,構建錯誤響應報文;

        varnish的處理流程:
            1.vcl_recv --> vcl_hash --> vcl_hit --> vcl_deliver
            2.vcl_recv --> vcl_hash --> vcl_hit --> vcl_pass --> vcl_fetch -->vcl_deliver
            3.vcl_recv --> vcl_hash --> vcl_miss --> vcl_fetch --> vcl_deliver
            4.vcl_recv --> vcl_hash --> vcl_miss --> vcl_pass --> vcl_fetch --> vcl_deliver
            5.vcl_recv --> vcl_pass --> vcl_fetch --> vcl_deliver
            6.vcl_recv --> vcl_pipe

    3.varnish 4.0+狀態引擎包括:
        vcl_recv:接收請求,而且判斷是否可使用緩存數據;
        vcl_hash:對於從backend端取回的數據,若是可被緩存,則進行哈希計算;
        vcl_hit:對於請求的資源能夠在緩存對象中直接獲取;
        vcl_miss:對於請求的資源沒法在緩存對象中直接獲取;
        vcl_deliver:構建響應報文;
        vcl_pass:對於原本能夠從緩存中查找到資源明確的設置不使用緩存;多數用於私有緩存的查找策略;
        vcl_pipe:對於沒法理解的請求,直接按照原樣的封裝直接代理至backend端;
        較於varnish3.0新增:
            vcl_backend_fetch:從backend端取回數據;
            vcl_backend_response:處理從backend取回的數據;
            vcl_backend_error:本地發生錯誤時,構建錯誤響應報文;
            vcl_synth:主要用於緩存修剪及信息發送;(由varnish3.0中的error變化而來)
            vcl_purge:修剪緩存;

        varnish的處理流程:
            1.vcl_recv --> vcl_hash --> vcl_hit --> vcl_deliver
            2.vcl_recv --> vcl_hash --> vcl_hit --> vcl_pass --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver
            3.vcl_recv --> vcl_hash --> vcl_pass --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver
            4.vcl_recv --> vcl_hash --> vcl_miss[ --> vcl_pass ] --> vcl_backend_fetch --> vcl_backend_response --> vcl_deliver
            5.vcl_recv --> vcl_hash --> vcl_purge --> vcl_synth
            6.vcl_recv --> vcl_hash --> vcl_pipe
            7.vcl_recv --> vcl_hash --> waiting
                                                                    ↑                                   ↓
                                                                     ←←←←←

        varnish中還有兩個特殊的狀態引擎:
            vcl_init:
                在處理任何請求以前要調用此引擎,主要用於初始化VMODs;
            vcl_fini:
                在全部的請求都已經處理結束,在VCL的配置被丟棄時調用此引擎,主要用於清理VMODs;

VCL的語法格式:
    1.與C、C++語言的語法很是類似,能夠支持C、C++或perl風格的註釋方式:
        //, #, /* ... */
    2.VCL不支持循環和跳轉語句;但能夠是if條件分支(單分支、雙分支及多分支);
        if的單分支格式:
            if (condition) {
                ...;
            }
        if的雙分支格式:
            if (condition) {
                ...;
            } else {
                ...;
            }
        if的多分支格式:
            if (condition1) {
                ...;
            } elseif (condition2) {
                ...;
            } else {
                ...;
            }
    3.全部的字符串內容應該放置於""以內,且不能使用換行符;
    4.支持內建和自定義的ACL;
    5.支持豐富的操做符:=(賦值符號), ==(等值比較), >, >=, <, <=, !, &&(與運算), ||(或運算), ~
    6.使用return()關鍵字來決定下一個處理流程使用哪一個引擎,且return()關鍵字無返回值;
    7.支持內建變量及自定義變量,而且內建變量之間存在依賴關係,只能在特定的引擎中調用特定的內建變量;
        set var_name = value
        unset var_name

VCL中的內建變量:
    req.*:request,表示客戶端發送來的請求報文相關的變量;
    bereq.*:backend request,由varnish向backend端主機發送請求的相關變量;
    resp.*:response,由varnish響應給前端設備或客戶端的響應報文的相關變量;
    beresp.*:backend response,由backend主機響應給varnish的響應報文的相關變量;
    obj.*:存在在緩存空間中的緩存對象相關的變量,只讀;

    經常使用的內建變量:
        req類:
            req.http.HTTP_HEADER_NAME:
                req.http.Cache-Control
                req.http.User-Agent
                req.http.Host:
                ...
            req.url:客戶端發送來的請求報文中的URL相關信息;
                if (req.url ~ (?i)\.php$) {
                    return(pass);
                }
            req.method:客戶端發送來的請求報文中的請求資源的方法;
            req.proto:客戶端發送來的請求報文中使用的http協議版本;

        bereq類:
            bereq.http.HTTP_HEADER_NAME:
                bereq.http.Cache-Control
                bereq.http.User-Agent
                bereq.http.Host:

            bereq.url:varnish向backend端發送的請求報文中的URL相關信息;
            bereq.method:varnish向backend端發送的請求報文中的請求資源的方法;
            bereq.proto:varnish向backend端發送的請求報文中使用的http協議版本;
            bereq.backend:指明要調度的後端主機;

        resp類:
            resp.http.HTTP_HEADER_NAME:
            resp.status:varnish自身向客戶端發送的響應報文中的響應狀態碼;
            resp.proto:varnish自身向客戶端發送的響應報文中的http協議版本號;

        beresp類:
            beresp.http.HTTP_HEADER_NAME:
            beresp.status:backend端主機向varnish發送的響應報文中的響應狀態碼;
            beresp.proto:backend端主機向varnish發送的響應報文中的http協議版本號;
            beresp.backend.name:backend端主機型varnish發送的響應報文中的主機名;
            beresp.ttl:backend端主機響應的內容剩餘的可緩存時長;

        obj類:
            obj.hits:指定的對象從緩存中命中的次數;(實時數值)
            obj.miss:指定的對象從緩存中未命中的次數;(實時數值)
            obj.ttl:指定的對象在緩存中剩餘有效緩存時長;

VCL的自定義變量:
    定義變量:
        set VAR_NAME = VALUE;
    取消定義的變量:
        unset VAR_NAME;

爲了方便展現下面的配置示例,說一下環境:
1.在安裝好的varnish緩存服務器主機上,/etc/varnish/varnish.params中修改監聽的後端服務器端口號爲80而不是默認的6081,其餘默認就能夠,方便顯示;
2.在/etc/varnish/varnish.params中VARNISH_LISTEN_PORT=80,而後保存退出重啓服務(重啓命令:systemctl reload varnish.service)
3.iptables -F關閉防火牆;
4.setenforce 0 更改SELinux的狀態,防止訪問受影響;

示例(1):設置若是緩存命中則顯示HIT,未命中顯示MISS(作測試專用):
在安裝好的varnish緩存服務器主機上,/etc/varnish/default.vcl文件中配置以下內容:
#要顯示在客戶端,因此咱們要在構建響應報文中作配置即vcl_deliver
sub vcl_deliver {
#若是緩存服務器中緩存沒有命中,obj.hits大於0便是緩存命中,在向客戶端發送的響應報文中顯示「HIT」,未命中則顯示「MISS」
if (obj.hits>0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
而且在/etc/varnish/default.vcl文件中添加一個後臺服務器主機172.16.75.2(直接修改默認的backend default段就能夠):
#監聽的端口號要和/etc/varnish/varnish.params中修改的保持一致
backend websrv1 {
.host = "172.16.75.2";
.port = "80";
}
運行時重載varnish服務,使其生效(也可使用交互式命令進入交互式模式:varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 ):
~]#varnish_reload_vcl

在後端主機172.16.75.2上配置主頁index.html中添加內容:Backend Server 7.5B
測試結果以下:
訪問172.16.75.1獲得的是172.16.75.2的主頁
緩存服務器memcached和varnish
在響應報文中,顯示第一次未命中MISS,第一次一定是MISS未命中,由於第一次緩存服務器和瀏覽器緩存中都沒有咱們指望的緩存:
緩存服務器memcached和varnish
CTRL+F5不使用瀏覽器緩存,直接從服務器端取數據,以下,X-Cache顯示HIT,下面的Pragma是no-cache,表示未使用瀏覽器端緩存(CTRL+F5刷新的結果):
緩存服務器memcached和varnish

示例2:人爲的設定對某特定資源的請求,不管緩存與否,強制其不檢查緩存;
#在客戶端請求報文中的URL若是匹配到「/test.html」字樣,不在緩存服務器端取值直接向後端服務器取值(pass起到的做用);
#仍然是在請求段配置需求;
#延續上面的配置段;
backend websrv1 {
.host = "172.16.75.2";
.port = "80";
}
#
sub vcl_recv {
if (req.url == "/test.html") {
return(pass);
}
#在客戶端請求報文中的URL若是匹配到「/login」或「/admin」字樣((?i)表明不區分後邊的字符大小寫),不在緩存服務器端取值直接向後端服務器取數據
if (req.url ~ "(?i)^/(login|admin)") {
return(pass);
}
}
在172.16.75.2主機上/var/www/html/中建立test.html且建立目錄admin/index.html,並添加內容方便測試,測試結果顯示使用CTRL+F5刷新,X-Cache顯示一直都是MISS,證實客戶端直接從後端服務器中取數據,就算緩存服務器中存在數據也直接pass過直接去日後端服務器取數據:
緩存服務器memcached和varnish

訪問admin目錄主頁,結果與預料一致,客戶端直接從後端服務器直接獲取數據:
緩存服務器memcached和varnish

示例3:對於某些特定類型資源,如:公開的圖片,音頻或視頻流媒體資源,取消此類資源上的私有標識,並強制設定其能夠由varnish進行緩存,且能夠設定緩存時長;
#由於設定的是緩存服務器上的配置,因此這裏是在後端服務器返回數據到緩存服務器段的配置;
sub vcl_backend_response {
#若是從後端服務器上返回的數據包括公共資源(s-maxage)和通用資源(max-age),再判斷緩存服務器端向後端服務器請求的數據報文的URL中若是包括流媒體格式的文件,就取消此類資源上的私有標識並設定緩存時長;
if (beresp.http.Cache-Control !~ "(s-maxage|max-age)") {
if (bereq.url ~ "(?i).(jpg|jpeg|png|gif|mp4|mp3|js|css)$") {
unset beresp.http.Set-Cookie;
set beresp.ttl = 86400s;
}
}
}

示例4:緩存對象的修剪:purge,ban
#若是緩存服務器端收到客戶端的請求帶有指定的PUGER方法,則直接return到puger段,直接return到synth進行緩存修剪並返回一個狀態碼和一段信息;
sub vcl_recv {
if (req.method == "PURGE") {
return(purge);
}
}
#必須通過purge修剪狀態引擎才能跳轉到synth;
sub vcl_purge {
return(synth(200,"Cache Purged"));
}

測試方法:
curl -X PURGE http://172.16.75.1/

測試結果,與咱們設置的內容一致,狀態碼200等:![](https://s1.51cto.com/images/blog/201807/12/769cb5660d62f9d22e8969ad0b014c0b.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

注意:修剪緩存對象的操做對於varnish來講,可能形成很是大的影響;若是修剪不當或者是惡意修剪,可能會直接致使backend端壓力劇增,甚至可能會出現故障,沒法正常提供服務;

對於此類修剪緩存對象的操做,務必要作好訪問控制法則:
更安全的緩存修剪策略示例:

#只容許本機修改
acl allowpurge {
"127.0.0.1";
}

設置修剪緩存的執行前提:
#若是客戶端使用PURGE方法請求訪問數據而且客戶端IP不是緩存服務器本機,那咱們只好返回403狀態碼而且提示對方,若是是咱們本機則直接return到purge段進行緩存數據的修剪;
sub vcl_recv {
if (req.method == "PURGE") {
if (client.ip !~ allowpurge) {
return(synth(403,"Purge Forbidden for" + client.ip));
}
return(purge);
}
}

sub vcl_purge {
return(synth(200,"Cache Purged"));
}

測試結果:
首先咱們使用非本地主機(172.16.74.1)使用PURGE方法訪問數據,以下結果:禁止訪問
緩存服務器memcached和varnish
再使用本機(172.16.75.1)127.0.0.1進行訪問,結果以下:顯示正確的狀態碼,已經容許本機進行PURGE
緩存服務器memcached和varnish

acl的定義語法:
acl ACL_NAME {
"HOSTNAME";
"IP_ADDRESS";
"NETWORK_ADDRESS"/PREFIX
}

示例5:設定讓Varnish可使用多個後端主機(Backend Server);
#/etc/varnish/default.vcl文件中配置;
backend websrv1 {
.host = "172.16.75.3";
.port = "80";
}

backend appsrv1 {
.host = "172.16.75.4";
.port = "80";
}
#若是客戶端請求的URL中包含以".php"結尾的信息,那麼就把這個請求發給appsrv1,不然就把這個請求發給websrv1;
sub vcl_recv {
if (req.url ~ "(?i).php$") {
set req.backend_hint = appsrv1;
} else {
set req.backend_hint = websrv1;
}
}

在後端服務器主機172.16.74.1的/var/www/html/中添加一個以「.php」結尾的首頁文件,進行測試訪問:
]#vim index.php
7.4A PHP info page.<br>
<?php
phpinfo();
?>
開始測試,結果以下顯示,能夠經過URL來實現動靜分離:
緩存服務器memcached和varnish

示例6:讓vanish充當負載均衡集羣的調度器,並對後端主機進行健康狀態檢測;
import directors;

backend websrv1 {
.host = "172.16.75.3";
.port = "80";
}

backend websrv2 {
.host = "172.16.75.4";
.port = "80";
}

sub vcl_init {
new websrvs = directors.round_robin();
websrvs.add_backend(websrv1);
websrvs.add_backend(websrv2);
}

sub vcl_recv {
if (req.url ~ "(?i).php$") {
set req.backend_hint = appsrv1;
} else {
set req.backend_hint = websrvs.backend();
}

if (req.url ~ "(?i)^/(login|admin)") {
  return(pass);
}

}

後端主機的健康狀態檢測:
backend websrv1 {
.host = "172.16.75.3";
.port = "80";
.probe = {
#.url = "/healthcheck"; //.url和.requset只能選一個,後者較爲精準;
.timeout = 1s;
.interval = 2s;
.window = 5;
.threshold = 3;
.request =
"GET /healthcheck.html HTTP/1.1"
"Host: www.qhdlink.com"
"Connection: close";
.expected_response = 200;
}
}

說明:
.probe:定義開啓對於指定的backend server進行健康狀態檢測;
.url:在執行健康狀態檢測時須要請求的URL,若是省略,默認爲/;
.timeout:健康狀態檢測時被標識爲失敗的超時時間;
.interval:檢測頻率,即:多長時間進行一次健康狀態檢測;
.window:基於最近的多少次檢測結果來判斷後端主機的健康狀態;
.threshold:閾值,在最近的.window次的檢測中,至少應該有.threshold次是成功的,纔會標識後端主機的健康狀態爲"healthy"或"Happy";不然標識後端主機的監控狀態爲"sick";
.request:對後端主機進行健康狀態檢測時發送的請求報文的具體內容;
.expected_response:對後端主機進行健康狀態檢測時,指望後端主機發送的響應報文中所包含的響應狀態碼,默認是200;

若是想要爲多個backend設置統一的健康狀態檢測方法,能夠事先定義健康狀態檢測方法,而後再在backend中引用此方法便可;

probe httpcheck {
.url = "/hc.html";
.timeout = 1s;
.interval = 2s;
.window = 5;
.threshold = 3;
}

backend websrv1 {
.host = "172.16.75.3";
.port = "80";
.probe = httpcheck;
}

backend websrv2 {
.host = "172.16.75.4";
.port = "80";
.probe = httpcheck;
}

分別在後端服務器172.16.75.2和172.16.74.1的/var/www/html/中設置一個健康狀態監測網頁hc.html,使用varnishadm交互模式進行測試:
兩個後臺都正常運行時:
緩存服務器memcached和varnish
關閉172.16.75.2後進行健康監測,結果以下:
[root@chenliang html]# systemctl stop httpd.service
下圖顯示,172.16.75.2已經sick:
緩存服務器memcached和varnish
上面就是健康測試機制。

varnish的運行時參數:
varnish的線程模型(Threads Model):
cache-worker:用於處理從前端發送來的請求的線程模型;每一個請求都有一個該線程進行處理;
cache-main:用於管理和啓動cache功能的線程模型;
ban lurker:用於實現基於正則表達式的模式匹配作緩存數據對象的修剪的進程模型;使用此類方式進行修剪時,不許確的正則表達式匹配規則有可能會對緩存對象形成誤傷;
acceptor:用來接受新鏈接創建請求的線程模型;
epoll/kqueue:用於管理線程池,實現併發處理的線程模型;
expire:用於清理過時緩存數據對象內容的線程模型;
backend poll:用於對後端主機進行健康狀態檢測的線程模型;

運行時參數就是線程模型在運行時的工做參數;

經常使用的運行時參數:
    thread_pool_add_delay:每次建立新線程以前,所須要的延遲時間;默認爲0s;
    thread_pool_destroy_delay:兩次終止線程之間的延遲時間;默認爲1s;
    thread_pool_fail_delay:在建立新線程失敗以後,建立新線程以前的延遲時間,默認爲0.2s;
    thread_pool_max:每一個線程池中能夠激活的線程的最大數量;
    thread_pool_min:每一個線程池中能夠保有的活躍線程的最小值;也能夠理解爲:每一個線程池中最大的空閒線程數量;
    thread_pool_timeout:對於那些超過thread_pool_min數量的全部的空閒線程的銷燬的等待時間;
    thread_pools:定義了能夠開啓的線程池的最大數量,其值最好不要超過最大CPU核心數;

    在線程池的內部,每一個有前端發送來的請求都須要一個worker線程予以處理,varnish的併發處理能力:
        thread_pool * thread_pool_max

    vcl_dir
  Value is: /etc/varnish (default)
  Default is: /etc/varnish

  Directory from which relative VCL filenames (vcl.load and include) are opened.

    vmod_dir
        Value is: /usr/lib64/varnish/vmods (default)
  Default is: /usr/lib64/varnish/vmods

  Directory where VCL modules are to be found.

查看運行時參數:varnishadm命令行工具中查看:
查看全部運行時參數列表:
varnish> param.show -l
查看特定的運行時參數:
varnish> param.show PARAM_NAME

修改或設置運行時參數的值:
只讀的運行時參數不能被修改;
實時修改,當即生效:
varnish> param.set PARAM_NAME VALUE

示例:
    varnish> param.set thread_pool_min 1000

非實時修改,但永久生效:
    /etc/varnish/varnish.params
        在這個文件中,若是在修改的選項中加入-r表明只讀即不能在varnishadm中實時修改生效;

varnish的日誌區域(內存中直接存儲):
shared memory log區域:
計數器;
日誌信息;

varnish的日誌查看和日誌管理工具:
    1.varnishstat
        varnishstat - Varnish Cache statistics

        經常使用選項:
            -1:再也不連續的刷新顯示varnish的狀態信息,而是一次性的將即時的狀態信息直接顯示在標準輸出;
            -f FIELD:顯示指定的字段所表明的狀態屬性信息,一般與-1選項一同使用;字段描述時可使用通配符(*,?);

            示例:
                varnishstat -1 -f MAIN.cache_hit
                varnishstat -1 -f MAIN.cache_miss
                varnishstat -1 -f MAIN.c*

    2.varnishtop
        varnishtop - Varnish log entry ranking

        經常使用選項:
            -1:再也不連續的刷新顯示varnish的日誌信息,而是一次性的將即時的日誌信息直接顯示在標準輸出;
            -i taglist:選擇僅顯示指定標籤所對應的屬性信息,可使用","分隔多個標籤,可使用多個-i選項顯示,還可使用通配符;
                示例:
                    varnishtop -1 -i BereqMethod,ReqMethod
                    varnishtop -1 -i Bereq*
            -I [taglist:]regex:顯示指定標籤或全部標籤的值中能夠被"regex"所匹配的全部的日誌信息;
            -x taglist:選擇不顯示指定標籤所對應的屬性信息,可使用","分隔多個標籤,可使用多個-i選項排除對應的標籤,還可使用通配符;
            -X [taglist:]regex:排除顯示指定標籤或全部標籤的值中能夠被"regex"所匹配的全部的日誌信息;

    3.varnishlog
        varnishlog - Display Varnish logs

        注意:默認狀況下vanish會將全部的varnish風格的日誌信息記錄於共享內存域中,若是想要將此類日誌信息保存至文件系統中,CentOS系發行版的LInux系統中可使用varnishlog.service服務實現;
        日誌文件:/var/log/varnish/varnish.log

    4.varnishncsa
        varnishncsa - Display Varnish logs in Apache / NCSA combined log format

        注意:默認狀況下vanish會將全部的Apache combined格式的日誌信息記錄於共享內存域中,若是想要將此類日誌信息保存至文件系統中,CentOS系發行版的LInux系統中可使用varnishncsa.service服務實現;
        日誌文件:/var/log/varnish/varnishncsa.log

varnish中的內建函數和關鍵字:
    Function(函數):
        regsub(str, regex, sub)
            將str中被regex第一次匹配到的部分換成sub;能夠用於rewrite;
        regsuball(str, regex, sub)
            將str中全部可以被regex匹配到的部分都緩存sub;
        ban(boolean expression)
            修剪全部被boolean expression匹配的結果爲"TRUE"的緩存對象;
        hash_data(input)
            用於指明對哪些數據進行哈希運算,主要用於經過指定特定鍵的方式提供命中率和查找效率;
        synthetic(str)
            發送一段信息;
            能夠實現purge操做;

    Keyword(關鍵字)
        1.call subroutines:調用
        2.return(action)
        3.new
        4.set
        5.unset
相關文章
相關標籤/搜索