Varnish的相關知識,varnish的簡單應用

Varnish是一款高性能的緩存加速器,具備穩定,且效率更高,資源佔用更少等特色。css


緩存存儲的格式:html

    key-value:web

        key:訪問路徑,URL, hash正則表達式

         valueweb content       算法

    命中率:hit/(hit+miss)  express

        文檔命中率:從文檔個數進行衡量;編程

        字節命中率:從內容大小進行衡量;後端

      注意:瀏覽器

           緩存對象:生命週期;按期清理;緩存

        緩存空間耗盡:LRU(最近最少使用算法)

        可緩存對象,不可緩存對象(用戶私有數據)

 

緩存處理的步驟:

    接收請求 --> 解析請求 (提取請求的URL及各類首部)--> 查詢緩存 --> 新鮮度檢測 --> 建立響應報文 -->發送響應 --> 記錄日誌

 

新鮮度檢測機制:

 一、  過時日期:

    Expires;例:Expires:Thu, 04 Jun 2015 23:38:18 GMT,是在這個時間之前都有效

    Cache-Control:max-age;例:Cache-Control:max-age=600,緩存有效時間爲600s(秒)

 2、有效性再驗證:revalidate,就是查到緩存之後,去向服務器端發送一個條件式請求,

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

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

  若是原始內容消失,則響應404,此時緩存中的cacheobject也應該被刪除;

 三、條件式請求首部:

    If-Modified-Since:基於請求內容的時間戳作驗正;就是自從什麼時間開始發生改變

    If-Unmodified-Since:自從什麼時間開始沒有發生改變

     If-Match:是否匹配

    If-None-Match:是否你匹配

       Etag:fdsfad9345,擴展標籤,是校驗碼

 

瀏覽器發送一個請求,先通過緩存,若是緩存服務器沒有,就會×××器端來響應,若是這個報文能夠緩存,會緩存到緩存服務器,而後響應給瀏覽器;若是瀏覽器在發送一個相同的請求,若是緩存沒有過時,就會從緩存服務器直接響應的

 

常見的緩存服務開源解決方案:

      varnish squid 

 

要想操做varnish,須要使用varnish的操做語言vclvcl的配置文件首先要被c編譯器編譯成二進制格式,而後才被varnish加載使用

vcl: Varnish Configuration Language,緩存策略配置接口;基於「域」的簡單編程語言

varnish分爲管理進程和子進程   

管理進程:編譯VCL並應用新配置;監控vanish;初始化varnishCLI接口;

    子進程(Child/cache)包括:

       Acceptor:接收新的鏈接請求;

       workerthreads:處理用戶請求;

       Expiry:清理緩存中的過時對象;

       Log/stats:日誌相關的

     日誌:Shared Memory Log,共享內存日誌大小默認通常爲90MB,分爲兩部分,前一部分爲計數器,後一部分請求相關的數據;

 

varnish如何存儲緩存對象:

    file:單個文件;不支持持久機制;

    malloc:內存;

    persistent:基於文件的持久存儲;在生產中是不可用的

 

  varnish的安裝包在epel源中有提供,提供的是4.0版本的varnish,能夠直接安裝,

 

    varnish的配置文件爲/etc/varnish/default.vcl

    varnish的命令行參數的配置文件/etc/varnish/varnish.params

    varnish的服務文件在/usr/lib/systemd/system/varnish.service

 

配置varnish的三種配置應用方式:

    1varnishd應用程序的命令行參數;(定義varnish主程序的工做特性)

        監聽的socket, 使用的存儲類型等等;額外的配置參數;

        -pparam=value :設置額外的參數

        -rparam,param,... : 設定只讀參數列表;

        -fconfig:指定配置文件的,指到哪去讀vcl配置文件的

        -aaddress[:port][,......]:指定服務監聽的地址和端口的,能夠指定多個,默認監聽的端口是6081(提供服務的端口)和6082(管理接口)

        -s[name=]type[,options]:指定緩存使用哪種存儲機制的

        -Taddress[:port]:指定管理的地址和接口

        /etc/varnish/varnish.params:命令行參數的配置文件(CentOS7中經常使用)

 

    2-p選項指明的參數:(定義varnish各子進程或線程的工做特性)

         運行時參數:也可在程序運行中,經過其CLI進行配置;

 

    3vcl:配置緩存系統的緩存機制;(指明線程中的緩存功能的工做機制)

        經過vcl配置文件進行配置;

        先編譯,後應用;依賴於c編譯器;


下面以實例和和概念相結合的方式,講述下varnish的相關知識和簡單應用


172.16.249.195varnish所在的主機,

/etc/varnish/varnish.params文件中定義了varnish主程序的特性,即varnish啓動時的參數

   VARNISH_VCL_CONF=/etc/varnish/default.vcl :定義了從哪讀取vcl的配置

   VARNISH_LISTEN_PORT=6081:服務監聽的端口,沒指明地址表明全部地址

       VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1:定義了管理的地址

   VARNISH_ADMIN_LISTEN_PORT=6082 :定義了管理的接口

   VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,1G":緩存的存儲機制的定義

   VARNISH_TTL=120varnish聯繫後端服務器的超時時間

   ... ...

  

  修改緩存使用的機制,改成使用內存:VARNISH_STORAGE="malloc,128M"

 wKiom1Y3chCSv6wOAALQp2ZKC8w353.jpg

 提供一臺主機啓動httpd服務(172.16.249.115),提供測試頁

for i in{1..10};do echo "Page $i on Web1" > /var/www/html/test$i.html;done

wKiom1Y3cj6xt7uSAADnuWp70Eo611.jpg

/etc/varnish/default.vcl文件中的是vcl的配置,

修改配置:

wKioL1Y3co_xQgFXAABpHI1PdY8337.jpg

這一段是配置後端服務器地址和端口的

 

這樣就能夠啓動varnish了(systemctl  start  varnish.service

wKiom1Y3cnLQGWvQAAGQhkhGQ5s731.jpg


能夠看到啓動成功了,訪問測試一下,記得端口是6081

wKioL1Y3cq6RauHMAABEqeR3poY709.jpg

varnish的命令行工具:


   1varnishadm

    使用varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082,進入varnish的管理接口

        -S:指明密鑰文件所在位置,-T:指明端口和IP地址

       進入後,使用help能夠查看可使用的命令

wKiom1Y3cqGDA1aNAADqKvDC4LE907.jpg

   ping:探測後端服務器是否在線

   status:顯示子進程的工做狀態

   vcl.list:顯示全部可使用的vcl文件,

   vcl.load <configname><filename>:編譯vcl文件(filename),而後取一個名(configname

wKioL1Y3cyPDx0BXAABMs1aU06A950.jpg


active:指正在使用的vcl配置文件

available:可用的vcl配置文件

vcl.use <configname>:切換使用的vcl文件

wKiom1Y3cuex-DntAABFmY09Eew210.jpg

能夠看到如今使用的就是test這個vcl文件了

 

vcl.discard <configname>:刪除可用的vcl文件的

wKioL1Y3c2OieS_AAABwJZmNoEg988.jpg

    param.show [-l] [<param>] :顯示參數,

    param.show:顯示全部的參數

        -l:顯示詳細的信息

     param.show<param>:只顯示一個參數的信息

    param.set <param> <value>:設置參數的

wKiom1Y3c1ODg4H2AAH6xSrP8to769.jpg

storage.list:顯示正在使用的緩存列表

wKiom1Y3c3GDDj4CAABG5JQjY0c362.jpg


vcl.show boot:能夠顯示boot文件編譯之前的樣子

wKioL1Y3c63DmyibAAJi4yQNaOk455.jpg

backend.list:顯示後端服務器列表的

wKiom1Y3c3HxBV7nAABfynnXKT8834.jpg

   ban <field> <operator><arg> [&& <field> <oper> <arg>]...:清理緩存中的緩存對象

   ban.list:定義的ban規則的列表


  這能夠動態裝載vcl配置文件的,後續的不少操做都是在這個接口裏操做的


   2Log

    varnishlog :顯示日誌信息的,須要訪問一下,纔會出內容的

    varnishncsa:這個也是顯示日誌信息的的,須要訪問一下,纔會出內容的

    這兩個日誌信息的顯示格式不一樣,這兩個命令行接口的使用,若有須要能夠去網上搜索下

   3Top:排序後的信息

    varnishtop

   4Statistics:統計信息的

    varnishstat:顯示緩存相關的信息

        -l:顯示全部能夠顯示的字段

         這些字段中,經常使用的有:

            MAIN.cache_hit:緩存命中的次數

            MAIN.sess_conn:統計varnish已經處理過多少請求了

  MAIN.sess_drop:統計varnish已經丟棄過多少請求

   ... ...

       -f  NAME:只顯示指定字段的信息

vcl:

   stateengine:各引擎之間存必定程度上的相關性;前一個engine若是能夠有多種下游engine,則上游engine須要用return指明要轉移的下游engine

   vcl_recv

   vcl_hash

   vcl_hit

   vcl_miss

   vcl_fetch

   vcl_deliver

   vcl_pipe

   vcl_pass

   vcl_error

 

  vcl編程語言語法:

    (1)//, #, /* */ 用於註釋;會被編譯器忽略;

    (2)sub $name: 用於定義子例程;

        subvcl_recv { }

    (3)不支持循環;

    (4)有衆多內置的變量,變量的可調用位置與state engine有密切相關性;

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

    (6)""專用;

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

        條件判斷語句:

         if(CONDTION) {

          }else {

            }

      變量賦值:set  name=value

      撤銷變量的值:unset  name

   varnish中經常使用的變量:

    req.http.HEADER:調用request報文中http協議的指定的HEADER首部;

    req.http.X-Forwarded-For

    req.http.Auhtorization

    req.http.cookie

    req.request:請求方法

    client.ip:客戶端IP

  vclv3)的工做機制流程圖:

wKiom1Y3dPDx_mhKAADPjfhe-8k841.jpg

state engine workflow(v3):vclv3版本的引擎工做機制:

        vcl_recv--> vcl_hash --> vcl_hit --> vcl_deliver

        vcl_recv--> vcl_hash --> vcl_miss --> vcl_fetch --> vcl_deliver

        vcl_recv--> vcl_pass --> vcl_fetch --> vcl_deliver

        vcl_recv--> vcl_pipe

vclv4)的工做機制流程圖:

能夠去這裏查看https://www.varnish-software.com/book/4.0/_p_w_picpaths/simplified_fsm.svg

wKiom1Y3dSDjavX2AAQFgLlmzxo396.jpg

    state engine(v4)

        vcl_recv

        vcl_pass

        vcl_pipe

        vcl_hash

        vcl_hit

        vcl_miss

        vcl_backend_fetch

        vcl_backend_response

        vcl_backend_error

        vcl_purge

        vcl_synth

 state engine workflow(v4):vclv34版本的引擎工做機制跟v3相似,就再也不多解釋了

 

 下面演示操做vcl,實現一些簡單應用:CentOS7中演示,使用的varnish4.0的版本


首先備份一份/etc/varnish/default.vcl,複製/etc/varnish/default.vcl/etc/varnish/test.vcl

修改/etc/varnish/test.vcl配置文件:

sub vcl_recv {}裏面加入下面內容:

if (req.method == "PRI") {

       /* We do not support SPDY or HTTP/2.0 */

       return (synth(405));

    }

 

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

     req.method != "HEAD" &&

     req.method != "PUT" &&

     req.method != "POST" &&

      req.method != "TRACE" &&

     req.method != "OPTIONS" &&

     req.method != "DELETE") {

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

       return (pipe);

    }

 

   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);

    }

  return (hash);

而後保存,使用varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082進入管理接口

而後使用vcl.load test1 test.vcl 裝載剛在咱們編寫的配置文件,若是配置文件有錯,會報錯的;而後查看下vcl可用列表,使用vcl.use test1切換到test1

wKiom1Y3dbyyvFo7AACMv7DAbic123.jpg

這定義的是一些默認的信息,無法測試,能加載成功就沒問題了

下面修改test.vcl,在sub vcl_deliver {}中加入

if (obj.hits>0) {

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

    } else {

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

    }

這是本身定義的一個響應報文首部,若是命中就顯示HIT,沒命中顯示MISSobj.hits是命中的次數

保存退出,而後在varnishadm接口下輸入下面內容:

wKioL1Y3djTwpzQQAABENzg7mLc742.jpg


而後訪問測試下:用一臺虛擬機使用curl命令測試,-I選項是顯示報文首部信息的

wKiom1Y3dfmBkGnIAAJrYn9CHwg972.jpg

能夠看到第一次請求是是沒有緩存的,第二次就使用緩存了

 

varnish中的內置變量:

    變量種類:

        client

        server:是varnish自己相關的

        req:客戶端發的請求

        resp:緩存服務器或代理服務器響應的

       bereq:是varnish日後端服務器請求的

        beresp:後端服務器響應過來的內容

        obj:後段服務器響應過來的內容或者從緩存中取得的內容的屬性

        storage:緩存存儲有效性的

    bereq

       bereq.http.HEADERS:varnish發往backend server的請求報文的指定首部;

       bereq.request:請求方法;

      bereq.url:請求的url

      bereq.proto:使用的協議版本

      bereq.backend:指明要調用的後端主機;

    beresp

      beresp.proto:使用的協議版本

      beresp.status:後端服務器的響應的狀態碼

      beresp.reason:緣由短語;

      beresp.backend.ip:後端服務器的ip地址

      beresp.backend.name:後端服務器的主機名稱

      beresp.http.HEADER:backend server響應的報文的首部;

      beresp.ttl:後端服務器響應的內容的餘下的生存時長;

    obj

      obj.ttl:對象的ttl值;

       obj.hits:此對象從緩存中命中的次數;

    server

      server.ip:緩存服務器本身的ip地址

      server.hostname:緩存服務器本身的主機名

    req 

      rep.http

      rep.url

      ......

    resp

resp.http

resp.status

 ... ...

    storage

      storage.<name>.free_space:緩存空間的空閒空間大小

      storage.<name>.use_space:緩存空間的已用空間大小

      storage.<name>.happy:緩存是否還有效

    Functions(函數)

      banexpression):清理緩存的

      return()

      new()

      regsubstrregexsub):正則表達式替換,把str替換爲sub,但只替換第一次出現的

regsuballstrregexsub):正則表達式替換,把str替換爲sub,替換全部的

 

  詳細的varnish的內置變量等能夠查看官方文檔:

https://www.varnish-cache.org/docs/4.0/reference/vcl.html#varnish-configuration-language

 

在剛纔的test.vcl配置文件中修改,在sub vcl_deliver{}中修改以下:

wKioL1Y3dx6yrgZnAACUu-8zQSk670.jpg

而後在加載,使用

wKiom1Y3du3ByN2RAACDgkWQrTw851.jpg

測試下

wKioL1Y3d0iTcnz_AAJoUF_yO-Q236.jpg

能夠看到使用成功了

 

示例:強制對某資源的請求,不檢查緩存

 

修改test.vcl以下,在sub vcl_recv {}里加入:

if (req.url ~ "^/test7.html$") {

        return(pass);

    }

wKiom1Y3dyyBibSjAAEVJWofn3Y880.jpg

而後在varnishadm命令行接口中作,vcl.loadvcl.use

wKiom1Y3dyzTiO2XAABGVxRH91w988.jpg

而後作測試,首先請求其餘資源,能夠看到能使用緩存

wKioL1Y3d2jAPifWAAJjI9Yie7c876.jpg

而後請求test7.html

wKioL1Y3d52zvJOJAAKCluKguXI696.jpg

能夠看到沒有使用緩存

 

 

  強制對下面兩類資源的請求,不檢查緩存;

    /admin

    /login

修改test.vcl配置文件,修改配置文件的sub vcl_recv {},修改成以下:

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

        return(pass);

     }

而後在後端的服務器的/var/www/html目錄下,建立每個admin目錄,而後提供測試頁,而後在varnishadm命令行接口中作,vcl.loadvcl.use,在測試能夠看到不緩存。這裏就再也不演示了,跟上面的相似。

 

示例:對特定類型的資源取消其私有的cookie標識,並強行設定其能夠varnish緩存的時長

 

修改test.vcl配置文件,在vcl_backend_response{}中,加入下面這些內容:

if (beresp.http.cache-control !~ "s-maxage") {

    if(bereq.url ~ "(?i)\.jpg$") {

        setberesp.ttl = 3600s;

        unsetberesp.http.Set-Cookie;

    }

if(bereq.url ~ "(?i)\.css$") {

    setberesp.ttl = 600s;

    unsetberesp.http.Set-Cookie;

     }

}

wKiom1Y3d2GBP1CmAAFqPZUbuEQ583.jpg

而後在varnishadm命令行接口中作,vcl.loadvcl.use

wKioL1Y3d52QcbVbAABC73FISZ8815.jpg

而後在後端主機上加載一個圖片,在/var/www/html目錄下,下載1.jpg2.jpg的圖片

而後在訪問測試下,由於首部顯示的不全,通常默認緩存一會就結束了,咱們在裏面定義的是定義的是3600s,這個緩存是緩存在varnish中,因此一個小時內請求這個資源都會使用緩存

wKiom1Y3d-3hM9j9AAEgrS0bJe0936.jpg

等幾分鐘,而後在訪問這個資源,會發現仍是使用緩存

wKioL1Y3eCqhynJtAAEeMr37bK0898.jpg

這樣就作好了,就是不太容易看出效果,

 

  backend server的定義:

    backendname {

        .attribute = "value";

     }       

        .host:backend主機的IP

        .portbackend主機監聽的PORT

        .probe:backend作健康狀態檢測;

           .probe = {...}

        .max_connections:並鏈接最大數量;

         

  後端主機的健康狀態檢測方式:

    probename {

      .attribute = "value";

       }       

        .url:斷定BE健康與否要請求的url;

        .expected_response:指望響應狀態碼;默認爲200

 

示例:作兩個後端服務器,而後作健康狀態檢測,再作下分離,讓訪問圖片資源的調度到一臺後端服務器上,訪問其餘資源的調度到令一臺後端主機上

修改test.vcl配置文件,以下:

wKioL1Y3eLaRSW_YAAHnAhO59QI206.jpg

而後在varnishadm命令行接口中作,vcl.loadvcl.use

wKiom1Y3eJOiuLZXAABDaptaM2I750.jpg

而後打開另外一個虛擬機(172.16.249.159)設置測試頁,for i in {1..10};do echo "Page $i in Web2" >/var/www/html/test$i.html ;done,這個主機裏沒有圖片

wKioL1Y3eM-zRJCiAADxTopW_yU120.jpg

varnishadm命令行接口中,使用backend.list,能夠查看到後端服務器的信息和狀態

wKiom1Y3eJPh8pWfAACTvvj4YDw851.jpg

訪問測試

wKiom1Y3eL_C9T_HAACo6jpTTMQ366.jpg

wKioL1Y3ePuy7qEIAABEP6rt7_U363.jpg

wKiom1Y3eL_yxFbQAABDady8aGM758.jpg



能夠看到圖片資源的是發送給web1主機(172.16.249.115)了,請求的.html資源的是發送給web2主機(172.16.249.159)了

 

示例:實現負載均衡

 

修改test.vcl配置文件:

wKioL1Y3eT_zvd5EAAGvnnKfxX4476.jpg

這樣負載均衡就定義好了,可是這樣很差查看效果,由於有緩存,爲了演示效果加入

wKiom1Y3eXjAOV76AAArZMyYuMY599.jpg

就是訪問test7.html時不讓緩存,這樣訪問時就能夠看到負載均衡效果了

而後在varnishadm命令行接口中作,vcl.loadvcl.use

訪問測試

wKioL1Y3ecOiQsY3AAHqHss6o9s378.jpg

能夠看懂訪問test7.html時是負載均衡,訪問其餘資源時,是使用的緩存,因此不會變

 

或者使用這個方式測試,每次使用一個新資源範圍,也能夠看到負載均衡效果

wKioL1Y3edvCIZraAAElV1bnW2M186.jpg

直接在物理機中測試也行,物理機中的瀏覽器訪問時是不容許緩存的,因此能夠看到負載均衡效果,若是你的物理機的瀏覽器對這些資源是容許緩存的話,就只能用上面的方法定義一個資源,讓它不緩存

wKiom1Y3eQOxPvbEAABBKtueRWI108.jpg

wKioL1Y3eUDhtFFJAABDXx0gHiU169.jpg

wKiom1Y3ebOg0jwIAABE74RCfio951.jpg

wKioL1Y3ee_yHHVkAABHmfuSttk601.jpg

能夠負載均衡

這樣負載均衡就作好了

 

若是有不明白的配置能夠到這個鏈接下去查看varnish的官方配置示例:https://www.varnish-cache.org/trac/wiki/VCLExamples

相關文章
相關標籤/搜索