Linux自學筆記——varnish

Web Cache

       緩存:緩存就是數據交換的緩衝區(cache),當某一硬件要讀取數據時,會首先從緩存中查找需要的數據,如果找到了則直接執行,找不到的話則從內存中找。由於緩存的運行速度比內存快很多,故緩存的作用就是幫助硬件更快的運行。

       程序具有局部性:時間局部性,空間局部性。

       緩存存儲方式:key-value

              Key:訪問路徑,url,hash

              Value:web content

       熱點數據:局部性的數據;

       命中率:hit/(hit+miss)

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

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

       注意:

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

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

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

       緩存處理的步驟:

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

       新鮮度檢測機制:

              過期日期:

                     HTTP/1.0 Expires

                            Expires:Thu,04 Jun 2015 23:38:18  GMT

                     HTTP/1.1 Cache-Control:max-age

                            Cache-Control:max-age=600

              有效性再驗證:revalidate

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

                     如果原始內容發生改變,則正常響應 , 響應碼爲200;

                     如果原始內容消失,則響應404,此時緩存中的cache object也應該被刪除;

              條件式請求首部:

                     If-Modified-Since:基於請求內容的時間戳驗證;

                     If-Unmodified-Since

                     If-Match

                     If-None-Match

                            Etag: faiy89345

常用的開源解決方案:squid ,varnish,本文重點介紹varnish;

 

Varnish

       程序架構圖:

              image.png                                               

       管理進程:編譯vcl並應用新配置;監控varnish;初始化varnish;CLI接口

       Child/cache

              Acceptor:接收新的連接請求;

              worker threads:處理用戶請求;

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

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

       vcl:Varnish Configuration Language

              保存策略配置接口;

              基於“域”的簡單編程語言;

       內存分配和回收:

              malloc(),free()

       varnish如何存儲緩存對象?可以通過以下三種方式;

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

              malloc:內存

              persistent:基於文件的持久存儲;

       varnish的主要配置文件及工具:

              image.png

       配置varnish的三種應用:

1.      Varnish應用程序的命令行參數;

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

-p parm=value

-r  param,param,…:設定只讀參數列表;

 

/etc/varnish/varnish.params

   image.png

2.      –p選項指明的參數:

運行時參數:

   也可在程序運行中,通過其CLI進行配置;

3.      vcl:配置緩存系統的緩存機制;

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

先編譯,後應用;

   依賴於c編譯器;

      

Note

1)      varnish是一個web代理緩存服務器,既然是代理就要代表原始web服務器工作,所以,接收的用戶請求會首先發送到varnish,那這樣一來按理說就應該監聽在80端口;其實不然,爲了防止和本機的80端口起衝突,varnish默認是監聽在6081端口的;這是因爲雖然varnish爲代理緩存服務器,但並不會讓其直接面向用戶,而是通過前端的nignx或者haproxy將用戶的請求反代至varnish,由varnish完成緩存管理,如果本地緩存沒有,varnish再去查找原始服務器,如果有就直接返回給前端反代服務器。      

2)      6082端口爲基於命令行工具去管理和控制varnish的接口,爲了安全起見監聽在本機的127.0.0.1的地址;

 

演示:使用varnish代理緩存後端web服務

實驗環境:兩臺服務器,一臺作varnish代理緩存服務器,一臺作後端服務器;

Ip地址分配:

       varnish緩存服務器:192.168.19.203

       後端RS:192.168.19.143

1.      配置文件/etc/varnish/varnish.params如下,(一般默認不改變)

    image.png

2.      編輯/etc/varnish/default.val文件,反向代理至後端服務器;

    image.png

3.      啓動varnish服務並查看端口;

    image.png

4.      訪問網站測試;

    image.png

Note:後面需要加端口6081,

 

命令行工具:

varnishadm命令以及vcl配置文件的重載:

重載vcl配置文件:

       varnish_reload_vcl

varnishadm命令:

       varnishadm -S /etc/varnish/secret -T IP:PORT

       image.png

 

vcl

       請求流程圖:

              image.png

state engine:各引擎之間存在一定程度上的相關性;前一個engine如果可以有多種下游engine,則說明engine需要用return指明要轉移的下游engine;

              vcl_recv

              vcl_hash

              vcl_hit

              vcl_miss

              vcl_fetch

              vcl_deliver

              vcl_pipe

              vcl_pass

              vcl_error

       編程語言語法:

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

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

sub vcl_recv {

 

}

3)      不支持循環;

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

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

6)      域專用 ;

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

條件判斷語句:

   if (CONDTION) {

 

   } else {

 

   }

變量賦值:set  name=value

   unset  name

 

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

          req.http.X-Forwarded-For

          req.http.Auhtorization

          req.http.cookie

   req.request:請求方法

   client.ip:客戶端IP;

 

state engine workflow(v3):

   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

 

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

 

   https://www.varnish-software.com/book/4.0/chapters/VCL_Basics.html

 

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

   }

定義在vcl_deliver中,向響應給客戶端的報文添加一個自定義首部X-Cache

   if (obj.hits>0) {

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

   } else {

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

   }

演示:通過判斷想應報文緩存命中的次數來判斷是否命中緩存;

1)      編輯配置文件/etc/varnish/default.vcl;

    image.png

2)      重載配置文件,過程如下;

    image.png

3)      瀏覽器測試;

   image.png 

 

Varnish中的內置變量:

       變量種類:

              client

              erver

              req

              resp

              bereq

              beresp

              obj

              storage

       bereq

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

              bereq.request:請求方法;

              bereq.url

              bereq.proto:協議的版本

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

       beresp

              beresp.proto:後端服務器響應的協議版本

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

              beresp.reason:原因短語;

              beresp.backend.ip:後端響應的ip

              beresp.backend.name:BE主機的主機名

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

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

       obj

              obj.ttl: 對象的ttl值;

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

       server

              server.ip

              server.hostname

       req

       resp

 

演示1:強制對某類資源的請求不檢查緩存,之類以login和admin爲例;

1)      提供測試頁面環境;

    image.png

2)      訪問測試;

    image.png

    可以看出,第一次沒有命中,但是以後都能命中的。

3)      現在我們修改配置文件,在vcl_recv下添加以下內容,強行對此資源不檢查緩存;

    image.png

4)      重新裝載配置文件,測試(裝載配置文件過程,這裏不再多說)

    image.png

可以看出,這兩次訪問,都沒有擊中緩存;

 

演示2:設定多個後端主機,並分別以負載均衡和動靜分離的方式調度;

動靜分離方式調度:

1)      提供RS2的php頁面測試環境;(注意,要安裝httpd+php)

    image.png

2)      編輯配置文件,添加內容如下;

    image.png

3)      重載配置文件,並測試;

訪問.php文件時:

image.png

Note:php右上角的圖片沒有顯示出來,是因爲靜態資源發往了192.168.19.144這臺主機,而這臺主機上又沒有這張圖片。所以顯示不出來;

訪問html文件時:

image.png

 

負載均衡調度:使用前需要導入:import director

    1)      編輯配置文件,首先導入import director模塊,內容如下;

    image.png

    2)      重載配置文件,測試;

    image.png

Note:varnish的負載均衡調度是對請求的不同資源的負載均衡調度,請求統一資源,它只會調度至一開始調度的服務器;

 

定義健康狀態監測;

backend server的定義:

backend name {

            .attribute = "value";

       }    

 

       .host: BE主機的IP;

       .port:BE主機監聽的PORT;

       .probe: 對BE做健康狀態檢測;

       .max_connections:並連接最大數量;

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

       probe name {

.attribute = "value";

       }    

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

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

              .request:發出的具體請求

              .window:基於最近的多少次檢查來判斷其健康狀態;

              .threshhold:最近.window中定義的這麼多次檢查中至有.threshhold定義的次數時成功的;

              .interval:監測額度;

              .timeout:超時時長;

 

演示3:設定varnish對後端主機做健康狀態監測;

1)      使用varnishadm命令可以查看後端主機是否做了檢測狀態監測;

    image.png

2)      編輯配置文件/etc/varnish/default.vcl,定義健康狀態監測的probe;

方法一:

image.png

  方法二:

       image.png

3)      重載配置文件,查看後端主機是否開啓健康狀態檢測;

    image.png

4)      瀏覽器訪問測試看是否能正常訪問;

    image.png

 

補充:

移除單個緩存對象

       purge用於清理緩存中的某特定對象及其變種(variants),因此,在有着明確要修剪的緩存對象時可以使用此種方式。HTTP協議的PURGE方法可以實現purge功能,不過,其僅能用於vcl_hit和vcl_miss中,它會釋放內存工作並移除指定緩存對象的所有Vary:-變種,並等待下一個針對此內容的客戶端請求到達時刷新此內容。另外,其一般要與return(restart)一起使用。

下面是個在VCL中配置的示例。

acl purgers {

"127.0.0.1";

       "192.168.0.0"/24;

}

 

sub vcl_recv {

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

              if (!client.ip ~ purgers) {

                     error 405 "Method not allowed";

              }

              return (lookup);

       }

}

sub vcl_hit {

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

              purge;

              error 200 "Purged";

       }

}

sub vcl_miss {

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

              purge;

              error 404 "Not in cache";

       }

}

sub vcl_pass {

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

              error 502 "PURGE on a passed object";

       }

}

 

客戶端在發起HTTP請求時,只需要爲所請求的URL使用PURGE方法即可,其命令使用方式如下:

# curl -I -X PURGE http://varniship/path/to/someurl

 

補充資料:

       varnish的線程模型:

              cache-worker線程

              cache-main線程:此線程只有一個,用於啓動caceh;

              ban luker

              acceptor

              epoll:線程池管理器

              expire:清理過期緩存

 

              varnish定義其最大併發連接數:線程池模型:

                     thread_pools:線程池個數;默認爲2;

                     thread_pool_max:單線程池內允許啓動的最多線程個數;

                     thread_pool_min

                     thread_pool_timeout:多於thread_pool_min的線程空閒此參數指定的時長後即被purge;

 

       varnish的param查看及改變:

              param.show [-l] [param]

              param.set [param] [value]

 

       varnish的命令行工具:

              varnishadm,

 

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

                     RxHeader User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.81 Safari/537.36

              其中:

                     RxHeader:稱爲tag, 基於tag過濾,可使用-i或-x選項;

                     User-Agent起始的內容:稱爲日誌信息,可使用-I或-X選項進行過濾;

 

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

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

                     -C: 忽略字符大小寫;

                     -d: 顯示已有日誌;

              varnishstat

                     -f field, field, ...

                     -l: 列出所有可用字段

                     -x: xml輸出格式

                     -j: json輸出格式

              varnishlog, varnishncsa




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