Varnish頁面緩存服務

1、緩存相關概念簡述

  • 時間局部性:一個數據被訪問過以後,可能很快會被再次訪問到;
  • 空間局部性:一個數據被訪問時,其周邊的數據也有可能被訪問到
  • 數據緩存:例如MySQL到web應用服務器之間的緩存服務器緩存的資源是數據緩存javascript

  • 頁面緩存:接入層和應用層中間的緩存服務器緩存的是可緩存的頁面,這層就是緩存層
  • 緩存命中率:hit/(hit+miss),通常高於30%命中率則是正向收益,好的設計系統能夠達到80%到95%以上
  • 字節命中率:按照數據的字節大小來計算命中率
  • 請求命中率:按照請求的數量來計算命中率
  • 代理式緩存:客戶端訪問緩存服務器,緩存服務器沒有命中緩存時到後端服務器請求數據,此時它做爲反向代理服務器工做,這種類型的緩存服務器叫作代理式緩存
  • 旁掛式緩存:客戶端親自去查詢數據庫,而且將數據複製給緩存服務器一份,下次先去找緩存服務器,若是沒有命中則再去數據庫服務器查詢,此時這種工做方式的緩存叫作旁掛式緩存,這個客戶端叫作胖客戶端(smart client)
  • private cache:私有緩存,用戶代理附帶的本地緩存機制
  • public cache:公共緩存,反向代理服務器的緩存功能
  • CND:Content Delivery Network 內容投遞系統
  • GSLB:全網均衡調度
  • 緩存有效性判斷機制:
    • 過時時間
    • 條件式驗證
      • Last-Modified/If-Modified-Since:基於文件的修改時間戳來判別
      • Etag/If-None-Match:基於文件的校驗碼來判別

過時時間驗證緩存是否失效顆粒度太大,若是頁面剛剛緩存應用服務器發生了變化,結果客戶端拿到的就是過時數據;從而加入了條件式驗證緩存的失效性,每次客戶端請求到達緩存服務器,緩存服務器都要拿本地的數據和應用服務器的數據比較時間戳,若是時間戳發生了變化則緩存新的數據;這樣雖然粒度小了,可是仍是會有問題,若是應用服務器在同一秒頁面數據變化了三次,而緩存服務器拿到的是第一份數據,這樣仍是會發生數據失效的問題;從而又引入了Etag(擴展標記)來標記惟一的頁面數據。此時雖然解決了數據失效性的問題,可是每次客戶端的請求都要去後端服務器作比較,對緩存和應用服務器都是不小的壓力,咱們不得不採起折中的解決方案就是「過時時間驗證+條件式驗證」,將不常常變更的頁面作過時時間驗證,變更頻繁的採用條件式驗證。php

請求報文用於通知緩存服務如何使用緩存響應請求:css

cache-request-directive = 
"no-cache" 不能使用緩存系統中的緩存響應我,必須先去應用服務器作緩存驗證
"no-store" 不能使用緩存系統中的緩存響應我,必須去應用服務器請求響應我
"max-age" "=" delta-seconds 
"max-stale" [ "=" delta-seconds ]
"min-fresh" "=" delta-seconds
"no-transform"
"only-if-cached"
cache-extension

響應報文用於通知緩存服務器如何存儲上級服務器響應的內容:html

cache-response-directive =
"public" 全部緩存系統均可以緩存
"private" [ "=" <"> 1#field-name <"> ] 僅可以被私有緩存所緩存
"no-cache" [ "=" <"> 1#field-name <"> ],可緩存,但響應給客戶端以前須要revalidation,即必須發出條件式請求進行緩存有效性驗正
"no-store" ,不容許存儲響應內容於緩存中
"no-transform" 不能轉換格式
"must-revalidate" 必須從新驗證
"proxy-revalidate" 
"max-age" "=" delta-seconds 私有緩存最大緩存時長
"s-maxage" "=" delta-seconds 公共緩存最大緩存時長
cache-extension

Web Page Cache解決方案:squid和varnish,它們的關係就像Apache和Nginxjava

2、varnish介紹

Varnish cache,或稱Varnish,是一套高性能的反向網站緩存服務器(reverse proxy server)web

varnish官方站點: http://www.varnish-cache.org/算法

Varnish頁面緩存服務

varnish擁有倆套配置文件;一套配置文件用於varnish自身進程的參數配置,另外一套用於定義緩存規則;定義緩存規則須要使用靈活的語言來定義,這就是VCL(varnish語言);應用時須要將VCL編寫的規則送給VCC編譯後才能運行,因此安裝varnish須要依賴gcc編譯器。chrome

varnish的安裝:yum install varnish -y,依賴epel源,目前CentOS7的epel源提供的版本是v4.0.5shell

varnish的程序環境:數據庫

  • /etc/varnish/varnish.params: 配置varnish服務進程的工做特性,例如監聽的地址和端口,緩存機制
  • /etc/varnish/default.vcl:配置各Child/Cache線程的緩存策略
  • /usr/sbin/varnishd:主程序
  • /usr/bin/varnishadm:命令行工具
  • /usr/bin/varnishhist
  • /usr/bin/varnishlog:查看內存中的日誌
  • /usr/bin/varnishncsa:以NCSA格式查看日誌
  • /usr/bin/varnishstat:查看緩存日誌狀態信息
  • /usr/bin/varnishtop:以rank方式查看日誌
  • /usr/bin/varnishtest:測試工具程序
  • /usr/sbin/varnish_reload_vcl:VCL配置文件重載程序
  • /usr/lib/systemd/system/varnish.service:varnish服務
  • /usr/lib/systemd/system/varnishlog.service:日誌持久的服務
  • /usr/lib/systemd/system/varnishncsa.service:日誌持久的服務

3、管理工具

一、varnishd

  • -s [name=]type[,options] :定義緩存數據的存儲方式
    • malloc[,size]:內存存儲,[,size]用於定義空間大小;重啓後全部緩存項失效
    • file[,path[,size[,granularity]]]:磁盤文件存儲,黑盒;重啓後全部緩存項失效
    • persistent,path,size:文件存儲,黑盒;重啓後全部緩存項有效;實驗階段,不建議使用
  • -a address[:port][,address[:port][...]:服務監聽端口,默認爲6081端口
  • -T address[:port]:管理服務監聽端口,默認爲6082端口
  • -f config:VCL配置文件
  • -F:運行於前臺
  • -p param=value:設定運行參數及其值; 可重複使用屢次
  • -r param[,param...]: 設定指定的參數爲只讀狀態

二、varnishstat

# varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss #顯示指定參數的當前統計數據
# varnishstat -l -f MAIN -f MEMPOOL #列出指定配置段的每一個參數的意義

三、varnishtop

  • -1:打印統計信息一次並退出,而不是持續更新的顯示
  • -i taglist:能夠同時使用多個-i選項,也能夠一個選項跟上多個標籤
  • -I <[taglist:]regex>:對指定的標籤的值基於regex進行過濾
  • -x taglist:排除列表
  • -X <[taglist:]regex>:對指定的標籤的值基於regex進行過濾,符合條件的予以排除

四、varnishadm

# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 #登陸管理程序
help [<command>] 獲取幫助
ping [<timestamp>] 測試服務器
auth <response>
quit 退出cli
banner
status 顯示狀態
start 啓動
stop 中止
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> 列出VCL詳細配置
backend.list [<backend_expression>] 列出後端服務器
backend.set_health <backend_expression> <state>
ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
ban.list

4、配置文件

默認配置文件:

RELOAD_VCL=1
VARNISH_VCL_CONF=/etc/varnish/default.vcl  #指定加載VCL配置文件
VARNISH_LISTEN_ADDRESS=192.168.1.5  #服務監聽的地址
VARNISH_LISTEN_PORT=6081  #默認監聽端口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1  #管理服務監聽的地址
VARNISH_ADMIN_LISTEN_PORT=6082 #管理服務監聽的端口
VARNISH_SECRET_FILE=/etc/varnish/secret  #鏈接祕鑰
VARNISH_STORAGE="malloc,256M"  #用內存提供保存緩存,大小爲256M
VARNISH_USER=varnish  #用戶身份
VARNISH_GROUP=varnish #組身份
DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300" #指定進程的運行參數

5、VCL

Varnish配置語言(VCL)是一種特定於域的語言,用於描述Varnish Cache的請求處理和文檔緩存策略。加載新配置時,由Manager進程建立的VCC進程將VCL代碼轉換爲C.此C代碼一般由gcc共享對象編譯。而後將共享對象加載到cacher進程中。

  • varnish的有限狀態機:

Varnish頁面緩存服務

VCL有多個狀態引擎,狀態之間存在相關性,但狀態引擎彼此間互相隔離;每一個狀態引擎可以使用return(x)指明關聯至哪一個下一級引擎;每一個狀態引擎對應於vcl文件中的一個配置段,即爲subroutine

倆個特殊的引擎:

vcl_init:在處理任何請求以前要執行的vcl代碼:主要用於初始化VMODs;
vcl_fini:全部的請求都已經結束,在vcl配置被丟棄時調用;主要用於清理VMODs;

一、vainish默認的VCL配置

默認VCL配置也叫作隱式規則,在配置文件中沒法看到,即便咱們修改了配置文件,默認配置規則也是在最後作處理。

varnish> vcl.show -v boot  #在客戶端cli工具中查看
sub vcl_recv {
    if (req.method == "PRI") {  #若是客戶端的請求方法是PRI,不支持SPDY或HTTP/2.0
        return (synth(405));  #則構建一個405的包響應給客戶端
    }
    if (req.method != "GET" &&  #若是客戶端的請求方法不是GET
      req.method != "HEAD" &&  #而且不是HEAD
      req.method != "PUT" &&  #而且不是PUT
      req.method != "POST" &&  #而且不是...
      req.method != "TRACE" &&
      req.method != "OPTIONS" &&
      req.method != "DELETE") {
        return (pipe);  #即,不是標準HTTP請求方法的交給pipe(管道)
    }
    if (req.method != "GET" && req.method != "HEAD") {  #請求方法不是GET和HEAD的
        return (pass);  #交給pass處理,也就是除了GAT和HEAD方法其餘的沒法緩存
    }
    if (req.http.Authorization || req.http.Cookie) {  #http的請求首部包含Authorization(認證)或Cookie,即我的專有信息
        return (pass);  #交給pass處理,由於這些帶有我的信息的數據沒法緩存
    }
    return (hash);  #以上的規則都沒有作處理的請求交給hash作處理,剩下的是能夠查詢緩存的請求了
}

sub vcl_pipe
sub vcl_pass
sub vcl_hash
sub vcl_purge
sub vcl_hit
sub vcl_miss
sub vcl_deliver
sub vcl_synth
sub vcl_backend_fetch
sub vcl_backend_response
sub vcl_backend_error
sub vcl_init
sub vcl_fini

二、內建函數

  • regsub(str, regex, sub)
  • regsuball(str, regex, sub)
  • ban(boolean expression)
  • hash_data(input)
  • synthetic(str)
  • hash_data():指明哈希計算的數據;減小差別,以提高命中率
  • regsub(str,regex,sub):把str中被regex第一次匹配到字符串替換爲sub;主要用於URL Rewrite
  • regsuball(str,regex,sub):把str中被regex每一次匹配到字符串均替換爲sub
  • return()
  • ban(expression)
  • ban_url(regex):Bans全部的其URL能夠被此處的regex匹配到的緩存對象
  • synth(status,"STRING"):生成響應報文

三、Keywords

  • call subroutine
  • return(action)
  • new
  • set
  • unset

四、操做符

  • ==, !=, ~, >, >=, <, <=
  • 邏輯操做符:&&, ||, !
  • 變量賦值:=

示例1:obj.hits是內建變量,用於保存某緩存項的從緩存中命中的次數

# vim /etc/varnish/varnish.params
VARNISH_LISTEN_PORT=80
# vim /etc/varnish/default.vcl
backend default {
    .host = "192.168.0.9";
    .port = "80";
}
sub vcl_deliver {
    if (obj.hits>0) {
        set resp.http.X-Cache = "HIT via" + " " + server.ip;
    } else {
        set resp.http.X-Cache = "MISS from " + server.ip;
    }
}
# systemctl restart varnish  #謹慎重啓varnish服務,會致使以前的緩存失效
# for i in {1..5}; do curl -I -s 192.168.0.8 |grep "X-Cache"; done  #在客戶端測試,第一次Miss
X-Cache: MISS from 192.168.0.8
X-Cache: HIT via 192.168.0.8
X-Cache: HIT via 192.168.0.8
X-Cache: HIT via 192.168.0.8
X-Cache: HIT via 192.168.0.8

五、內建變量

  • req.*:request,表示由客戶端發來的請求報文相關;
  • bereq.*:由varnish發往BE主機的httpd請求相關;
  • beresp.*:由BE主機響應給varnish的響應報文相關;
  • resp.*:由varnish響應給client相關;
  • obj.*:存儲在緩存空間中的緩存對象的屬性;只讀;

經常使用變量:

  • bereq.request, req.request:請求方法;
  • bereq.url, req.url:請求的url;
  • bereq.proto:請求的協議版本;
  • bereq.backend:指明要調用的後端主機;
  • req.http.Cookie:客戶端的請求報文中Cookie首部的值;
  • req.http.User-Agent ~ "chrome";
  • beresp.status, resp.status:響應的狀態碼;
  • reresp.proto, resp.proto:協議版本;
  • beresp.backend.name:BE主機的主機名;
  • beresp.ttl:BE主機響應的內容的餘下的可緩存時長;
  • obj.hits:此對象從緩存中命中的次數;
  • obj.ttl:對象的ttl值
  • server.ip:varnish主機的IP;
  • server.hostname:varnish主機的Hostname;
  • client.ip:發請求至varnish主機的客戶端IP;

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

# vim /etc/varnish/default.vcl
sub vcl_recv {
    if (req.url ~ "(?i)^/(login|admin)") {  #"?i"表示忽略大小寫,匹配到url中帶有login或admin的不查詢緩存
        return(pass);
    }
}
# varnish_reload_vcl
# for i in {1..5}; do curl -I -s http://192.168.0.8/login |grep "X-Cache"; done  #客戶端測試
X-Cache: MISS from 192.168.0.8  #所有Miss
X-Cache: MISS from 192.168.0.8
X-Cache: MISS from 192.168.0.8
X-Cache: MISS from 192.168.0.8
X-Cache: MISS from 192.168.0.8
# for i in {1..5}; do curl -I -s http://192.168.0.8/admin |grep "X-Cache"; done
X-Cache: MISS from 192.168.0.8
X-Cache: MISS from 192.168.0.8
X-Cache: MISS from 192.168.0.8
X-Cache: MISS from 192.168.0.8
X-Cache: MISS from 192.168.0.8
# for i in {1..5}; do curl -I -s http://192.168.0.8/ |grep "X-Cache"; done  #其餘網頁正常查詢緩存
X-Cache: MISS from 192.168.0.8
X-Cache: HIT via 192.168.0.8
X-Cache: HIT via 192.168.0.8
X-Cache: HIT via 192.168.0.8
X-Cache: HIT via 192.168.0.8

示例3:對於特定類型的資源,例如公開的圖片等,取消其私有標識,並強行設定其能夠由varnish緩存的時長

sub vcl_backend_response {
    if (beresp.http.cache-control !~ "s-maxage") {
        if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
            unset beresp.http.Set-Cookie;
            set beresp.ttl = 3600s;
        }
    }
}

示例4:在報文首部添加真正的客戶端IP,使得後端server能夠記錄真正客戶端來源

[root@varnish ~]# vim /etc/varnish/default.vcl
sub vcl_recv {
    if (req.restarts == 0) {  #匹配沒有被重寫的URL請求,即第一次請求
        if (req.http.X-Forwarded-For) {  #變量存在而且有值則爲真
            set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;  #將真正的client.ip添加到此變量中,用","隔開
        } else {
            set req.http.X-Forwarded-For = client.ip;  #若是變量不存在或值爲空,則直接將client.ip賦值與
        }
    }
}
[root@varnish ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
varnish> vcl.load conf1 /etc/varnish/default.vcl
varnish> vcl.use conf1
varnish> vcl.list   
available       0 boot
available       0 reload_2018-07-14T09:55:58
active          0 conf1  #當前正在使用的配置
[root@web1 ~]# vim /etc/httpd/conf/httpd.conf
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
[root@web1 ~]# systemctl restart httpd
[root@client ~]# for i in {1..5}; do curl -I -s http://192.168.0.8/login |grep "X-Cache"; done #在客戶端測試
[root@web1 ~]# tail /var/log/httpd/access_log 
192.168.0.8 - - [14/Jul/2018:09:56:49 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.8 - - [14/Jul/2018:09:56:49 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.8 - - [14/Jul/2018:09:56:49 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.8 - - [14/Jul/2018:09:56:49 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.8 - - [14/Jul/2018:09:56:49 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.7 - - [14/Jul/2018:10:25:11 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.7 - - [14/Jul/2018:10:25:11 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.7 - - [14/Jul/2018:10:25:11 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.7 - - [14/Jul/2018:10:25:11 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"
192.168.0.7 - - [14/Jul/2018:10:25:11 +0800] "HEAD /login HTTP/1.1" 301 - "-" "curl/7.29.0"  #拿到了真正客戶端IP,而不是以前的varnish服務器的IP

示例5:訪問控制,拒絕curl客戶端的訪問

sub vcl_recv {
    if(req.http.User-Agent ~ "curl") {
        return(synth(403));
    }
}

六、緩存對象的修剪:purge

1) 能執行purge操做

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

2) 什麼時候執行purge操做

sub vcl_recv {
    if (req.method == "PURGE") {
        return(purge);
    }
    ...
}

示例6:清除指定緩存

[root@varnish ~]# vim /etc/varnish/default.vcl
acl purgers {
    "127.0.0.0"/8;
    "192.168.0.0"/24;
}
sub vcl_recv {
    if (req.method == "PURGE") {
        if (!client.ip ~ purgers) {
            return(synth(405,"Purging not allowed for " + client.ip));
        }
        return(purge);
    }
}
varnish> vcl.load conf3 /etc/varnish/default.vcl
varnish> vcl.use conf3
[root@client ~]# curl -I http://192.168.0.8/
X-Cache: HIT via 192.168.0.8
[root@client ~]# curl -I -X "PURGE"  http://192.168.0.8/
[root@client ~]# curl -I http://192.168.0.8/
X-Cache: MISS from 192.168.0.8

七、緩存對象的修剪:Banning

1)varnishadm: ban &lt;field&gt; &lt;operator&gt; &lt;arg&gt;

varnish> ban req.url ~ (?i)^/javascripts

2)在配置文件中定義,使用ban()函數

sub vcl_recv {
    if (req.method == "BAN") {
        ban("req.http.host == " + req.http.host + " && req.url == " + req.url);  #將規則拼接起來傳遞給ban函數
        return(synth(200, "Ban added"));
    }
}
# curl -I -X "BAN" http://192.168.0.8/javascripts/

6、多個後端主機實現調度功能

一、動靜分離示例:

backend default {
    .host = "172.16.0.9";
    .port = "80";
}
backend appsrv {
    .host = "172.16.0.10";
    .port = "80";
}
sub vcl_recv {
    if (req.url ~ "(?i)\.php$") {
        set req.backend_hint = appsrv;
    } else {
        set req.backend_hint = default;
    }
}

二、輪詢調度

import directors;
backend srv1 {
    .host = "192.168.0.9";
    .port = "80";
}
backend srv2 {
    .host = "192.168.0.10";
    .port = "80";
}
sub vcl_init {
    new websrvs = directors.round_robin();  #round_robin()調度算法,不支持加權
    websrvs.add_backend(srv1);
    websrvs.add_backend(srv2);
}
sub vcl_recv {
    set req.backend_hint = websrvs.backend();
}

三、基於cookie的session sticky

sub vcl_init {
    new h = directors.hash();
    h.add_backend(one, 1);
    h.add_backend(two, 1);
}
sub vcl_recv {
    set req.backend_hint = h.backend(req.http.cookie);
}

四、隨機調度,支持權重

sub vcl_init {
    new websrvs = directors.random();
    websrvs.add_backend(srv1, 1);
    websrvs.add_backend(srv2, 2);
}

五、後端健康檢查

.probe:定義健康狀態檢測方法;
.url:檢測時要請求的URL,默認爲」/";
.request:發出的具體請求;
.request =
"GET /.healthtest.html HTTP/1.1"
"Host: www.dongfei.tech"
"Connection: close"
.window:基於最近的多少次檢查來判斷其健康狀態;
.threshold:最近.window中定義的這麼次檢查中至有.threshhold定義的次數是成功的;
.interval:檢測頻度;
.timeout:超時時長;
.expected_response:指望的響應碼,默認爲200;

import directors;
probe http_chk {
        .url = "/index.html";
        .interval = 2s;
        .timeout = 2s;
        .window = 10;  #最近10次檢查
        .threshold = 7;  #有7次成功則爲健康主機
}
backend srv1 {
        .host = "192.168.0.9";
        .port = "80";
        .probe = http_chk;
}
backend srv2 {
        .host = "192.168.0.10";
        .port = "80";
        .probe = http_chk;
}
sub vcl_init {
        new websrvs = directors.random();
        websrvs.add_backend(srv1, 1);
        websrvs.add_backend(srv2, 2);
}
sub vcl_recv {
        set req.backend_hint = websrvs.backend();
}
varnish> backend.list #查看後端主機健康狀態信息     
Backend name                   Refs   Admin      Probe
srv1(192.168.0.9,,80)          3      probe      Healthy 10/10
srv2(192.168.0.10,,80)         3      probe      Healthy 10/10
varnish> backend.set_health srv1 sick|healthy|auto  #手動標記主機狀態 down|up|probe

設置後端的主機屬性:

backend BE_NAME {
    ...
    .connect_timeout = 0.5s;  #鏈接超時時間
    .first_byte_timeout = 20s;  #第一個字節20s不響應則爲超時
    .between_bytes_timeout = 5s;  #第一個字節和第二個字節間隔超時時間
    .max_connections = 50;  #最大鏈接數
}

7、varnish的運行時參數

最大併發鏈接數 = thread_pools * thread_pool_max

  • thread_pools:工做線程數,最好小於或等於CPU核心數量
  • thread_pool_max:每線程池的最大線程數
  • thread_pool_min:最大空閒線程數
  • thread_pool_timeout:空閒超過多長時間被清除
  • thread_pool_add_delay:生成線程以前等待的時間
  • thread_pool_destroy_delay:清除超出最大空閒線程數的線程以前等待的時間

8、日誌管理

virnish的日誌默認存儲在80M的內存空間中,若是日誌記錄超出了則覆蓋前邊的日誌,服務器重啓後丟失;須要更改配置使其永久保存到磁盤

# varnishstat -1 -f MAIN  #指定查看MAIN段的信息
# varnishstat -1 -f MAIN.cache_hit -f MAIN.cache_miss  #顯示指定參數的當前統計數據
MAIN.cache_hit              47         0.00 Cache hits
MAIN.cache_miss             89         0.01 Cache misses
# varnishtop -1 -i ReqHeader  #顯示指定的排序信息
   165.00 ReqHeader Accept: */*
   165.00 ReqHeader Host: 192.168.0.8
   165.00 ReqHeader User-Agent: curl/7.29.0
   165.00 ReqHeader X-Forwarded-For: 192.168.0.7

將日誌永久保存到:/var/log/varnish/varnish.log

# systemctl start varnishlog.service

以Apache/NCSA日誌格式顯示

# varnishncsa
192.168.0.7 - - [14/Jul/2018:12:34:23 +0800] "GET http://192.168.0.8/javascripts/test1.html HTTP/1.1" 200 11 "-" "curl/7.29.0"

9、ansible-role-varnish

# tree ansible-role-varnish/
ansible-role-varnish/
├── files
│   ├── default.vcl
│   ├── secret
│   └── varnish.params
├── handlers
│   └── main.yml
├── tasks
│   ├── copy.yml
│   ├── main.yml
│   ├── setup-varnish.yml
│   └── start.yml
└── templates
# find ansible-role-varnish/ -name *.yml -exec ls {} \; -exec cat {} \;
ansible-role-varnish/handlers/main.yml
- name: restart varnish
  service: name=varnish state=restarted
- name: reload vcl
  command: varnish_reload_vcl
ansible-role-varnish/tasks/start.yml
- name: start service
  service: name=varnish state=started
ansible-role-varnish/tasks/copy.yml
- name: copy configure file
  copy: src=varnish.params dest=/etc/varnish/varnish.params
  notify: restart varnish
- name: copy secret file
  copy: src=secret dest=/etc/varnish/secret
  notify: restart varnish
- name: copy default.vcl file
  copy: src=default.vcl dest=/etc/varnish/default.vcl
  notify: reload vcl
ansible-role-varnish/tasks/main.yml
- include: setup-varnish.yml
- include: copy.yml
- include: start.yml
ansible-role-varnish/tasks/setup-varnish.yml
- name: install yum-utils
  yum: name={{ item }} state=present
  with_items:
    - yum-utils
    - pygpgme
- name: Add epel repo
  yum_repository:
    name: alibaba
    description: epel
    baseurl: https://mirrors.aliyun.com/epel/7Server/x86_64/
    repo_gpgcheck: no
    gpgcheck: no
    enabled: yes
- name: install varnish
  yum: name=varnish state=present
# find ansible-role-varnish/files/* -exec ls {} \; -exec cat {} \;
ansible-role-varnish/files/default.vcl
#-------------------------------------------------
vcl 4.0;
import directors;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
}
probe http_chk {
        .url = "/index.html";
        .interval = 2s;
        .timeout = 2s;
        .window = 10;
        .threshold = 7;
}
backend srv1 {
    .host = "192.168.0.9";
    .port = "80";
    .probe = http_chk;
}
backend srv2 {
    .host = "192.168.0.10";
    .port = "80";
    .probe = http_chk;
}
sub vcl_init {
    new websrvs = directors.random();
    websrvs.add_backend(srv1, 1);
    websrvs.add_backend(srv2, 1);
}

sub vcl_recv {
        set req.backend_hint = websrvs.backend();
    if (req.restarts == 0) {
        if (req.http.X-Forwarded-For) {
            set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;
        } else {
            set req.http.X-Forwarded-For = client.ip;
        }
    }
    if(req.http.User-Agent ~ "curl") {
        return(synth(403));
    }
}

sub vcl_backend_response {
    if (beresp.http.cache-control !~ "s-maxage") {
        if (bereq.url ~ "(?i)\.(jpg|jpeg|png|gif|css|js)$") {
            unset beresp.http.Set-Cookie;
            set beresp.ttl = 3600s;
        }
    }
}

sub vcl_deliver {
    if (obj.hits>0) {
        set resp.http.X-Cache = "HIT via" + " " + server.ip;
    } else {
        set resp.http.X-Cache = "MISS from " + server.ip;
    }
}
#-------------------------------------------------
ansible-role-varnish/files/secret
7e40f334-d2e7-4edb-aecb-559519e456f9
ansible-role-varnish/files/varnish.params
RELOAD_VCL=1
VARNISH_VCL_CONF=/etc/varnish/default.vcl
VARNISH_LISTEN_ADDRESS=0.0.0.0
VARNISH_LISTEN_PORT=80
VARNISH_ADMIN_LISTEN_ADDRESS=0.0.0.0
VARNISH_ADMIN_LISTEN_PORT=6082
VARNISH_SECRET_FILE=/etc/varnish/secret
VARNISH_STORAGE="malloc,256M"
VARNISH_USER=varnish
VARNISH_GROUP=varnish
#DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"

感謝閱讀!

相關文章
相關標籤/搜索