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停止或重啓時會清除數據。
設計結構:
工作流程:
Varnish 與一般服務器軟件類似,分爲 master 進程和 child 進程。Master 進程讀入存儲配置文件,調用合適的存儲類型,然後創建 / 讀入相應大小的緩存文件,接着 master 初始化管理該存儲空間的結構體,然後 fork 並監控 child 進程。Child 進程分配若干線程進行工作,主要包括一些管理線程和很多 worker 線程。
Varnish 的某個負責接收新 HTTP 連接線程開始等待用戶,如果有新的 HTTP 連接過來,它總負責接收,然後喚醒某個等待中的線程,並把具體的處理過程交給它。Worker 線程讀入 HTTP 請求的 URI,查找已有的 object,如果命中則直接返回並回複用戶。如果沒有命中,則需要將所請求的內容,從後端服務器中取過來,存到緩存中,然後再回復。具體決策操作流程由vcl各狀態引擎實現
配置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