varnish:
varnish是一個Web應用程序加速器也被稱為高速緩存HTTP反向代理』瓯幔可以在HTTP的任何服務(wù)器的前端安裝它并將其配置為緩存服務(wù)器。varnish加速明顯,它通常加速到300- 1000倍惶翻,當然這也取決于你的架構(gòu)得运。varnish的主要特點膝蜈,除了它的性能,還有就是它的配置語言澈圈,VCL的靈活性彬檀。
varnish架構(gòu):
圖上顯示了Varnish架構(gòu)的框圖。該圖顯示了數(shù)據(jù)流在varnish的主要部分之間瞬女。
主程序段是Manager進程窍帝,它包含在varnishd二進制程序中。該Manager進程的任務(wù)是將任務(wù)(包括緩存)委派給子進程诽偷。Manager過程確保每個任務(wù)總是有一個進程坤学。
Manar的命令行界面(CLI)可通過以下方式訪問:1)varnishadm,如解釋中所述管理界面varnishadm部分报慕,2)varnish代理vagent2深浮,或 varnish管理控制臺(VAC(通過vagent2)。
Varnish處理HTTP請求的過程如下:
Receive(vcl_recv)狀態(tài):也就是請求處理的入口狀態(tài)眠冈,根據(jù)VCL規(guī)則判斷該請求是應該進入 pass(vcl_pass)或者是 pipe(vcl_pipe)或者是lookup(緩存本地查詢)飞苇,還是purge(vcl_purge)菌瘫。
Lookup 狀態(tài):進入該狀態(tài)后,會在hash表中查找數(shù)據(jù)布卡。若找到雨让,則進入hit(vcl_hit)狀態(tài),否則進入miss(vcl_miss)狀態(tài)忿等。
Pass(vcl_pass)狀態(tài):在此狀態(tài)下栖忠,對于請求會直接發(fā)往后端主機,進入到ackend_fetch(vcl_backend_fetch)狀態(tài)贸街。
Backend_Fetch(vcl_backend_fetch)狀態(tài):在此狀態(tài)下庵寞,對請求會向后端服務(wù)器進行獲取,發(fā)送請求薛匪,獲得數(shù)據(jù)捐川,并根據(jù)配置文件中對此類數(shù)據(jù)的緩存設(shè)置進行緩存或者其他操作。
Deliver(vcl_deliver)狀態(tài):將獲取到的數(shù)據(jù)發(fā)送給客戶端蛋辈,完成本次請求属拾。
內(nèi)置函數(shù)
vcl_recv:用于接收和處理請求;當請求到達varnish冷溶,通過判斷請求的數(shù)據(jù)來決定如何處理請求
vcl_pipe:用于將請求直接傳遞至后端主機渐白,并將后端響應原封不動返回給客戶端
vcl_pass:用于將請求直接傳遞給后端主機,但后端主機的響應并不緩存逞频,而是直接返回給客戶端
vcl_hit:在緩存中找到請求的內(nèi)容后自動調(diào)用
vcl_miss:在緩存中沒有找到請求的內(nèi)容后自動調(diào)用纯衍。用于判斷是否需要從后端服務(wù)器獲取內(nèi)容
vcl_hash:在vcl_recv調(diào)用后為請求創(chuàng)建一個hash值時,調(diào)用苗胀。此hash值將作為varnish中hash表的key
vcl_pruge:在收到 purge請求時襟诸,執(zhí)行此函數(shù),清空特定頁面/資源的緩存基协。
vcl_deliver:將在緩存中找到的請求的內(nèi)容發(fā)送給客戶端前調(diào)用歌亲。
vcl_backend_fetch:向后端主機發(fā)送請求前,調(diào)用澜驮∠菥荆可修改發(fā)往后端的請求
vcl_backend_response:獲得后端主機的響應后,調(diào)用杂穷。
vcl_backend_error:當從后端主機獲取資源時失敗時悍缠,調(diào)用。
vcl_init:VCL加載時調(diào)用此函數(shù)耐量,用于初始化varnish模塊(類似于awk中的BEGIN)
vcl_fini:當所有請求都離開當前VCL飞蚓,且當前VCL被棄用時,調(diào)用廊蜒。用于清理varnish模塊(類似于awk中的END)
內(nèi)建變量:
req.:request趴拧,表示由客戶端發(fā)來的請求報文相關(guān)溅漾;
bereq.:由varnish發(fā)往BE主機的httpd請求相關(guān);
beresp.:由BE主機響應給varnish的響應報文相關(guān)著榴;
resp.:由varnish響應給client相關(guān)樟凄;
obj.:存儲在緩存空間中的緩存對象的屬性;只讀兄渺;
常用變量:
bereq., req.*:
bereq.http.HEADERS
bereq.request:請求方法;
bereq.url:請求的url汰现;
bereq.proto:請求的協(xié)議版本挂谍;
bereq.backend:指明要調(diào)用的后端主機;
req.http.Cookie:客戶端的請求報文中Cookie首部的值瞎饲;
req.http.User-Agent ~ "chrome"
beresp., resp.:
beresp.http.HEADERS
beresp.status:響應的狀態(tài)碼口叙;
reresp.proto:協(xié)議版本;
beresp.backend.name:BE主機的主機名嗅战;
beresp.ttl:BE主機響應的內(nèi)容的余下的可緩存時長妄田;
obj.*
obj.hits:此對象從緩存中命中的次數(shù);
obj.ttl:對象的ttl值
server.*
server.ip varnish主機的ip
server.hostname varnish的主機hostname
client.*
lient.ip 請求客戶端的 ip
varnish配置文件
1.varnish.params 配置varnish服務(wù)進程的工作特性驮捍,例如監(jiān)聽的地址和端口疟呐,緩存機制;
通常這個配置文件不需要太大的改動东且。
一般較為常見的改動為
指定監(jiān)聽的服務(wù)端口:
VARNISH_LISTEN_PORT=6081
VARNISH_LISTEN_PORT=80
設(shè)置存儲類型以及大小;Varnish 4中默認使用malloc(即內(nèi)存)作為緩存對象存儲方式
VARNISH_STORAGE="malloc,256M"
VARNISH_STORAGE="malloc,1024M"
進程池配置启具,(視生產(chǎn)環(huán)境而定)
#DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"
- default.vcl 配置各Child/Cache線程的緩存策略; 配置個緩存默認文件
默認里面為空珊泳,這里可根據(jù)需求添加
vcl 4.0;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
}
sub vcl_backend_response {
}
sub vcl_deliver {
}
[root@cnetos7 varnish]#varnishadm -S secret -T 127.0.0.1:6082 可查看默認的 default.vcl配置
vcl.show -v boot
自己做的配置樣本:
vcl 4.0;
import directors; //加載后端負載均衡模塊
probe healthchk { //后端健康檢查
.url = "/.healthchk.html"; //檢測后端是否有.healthchk文件鲁冯,
.timeout = 2s; // 超時時長
.interval = 2s; //檢測頻度
.window = 8; // 基于最近的多少次檢查來判斷其健康狀態(tài)
.threshold = 5; //最近.window中定義的這么次檢查中至有.threshhold定義的次數(shù)是成功的
}
backend appsrv1 { //后端服務(wù)器 動態(tài)1
.host = "192.168.18.99";
.port = "80";
.probe = healthchk;
}
backend appsrv2 { //后端服務(wù)器 動態(tài)2
.host = "192.168.18.100";
.port = "80";
.probe = healthchk;
}
backend websrv1 { //后端服務(wù)器 靜態(tài)1
.host = "192.168.18.101";
.port = "80";
.probe = healthchk;
}
backend websrv2 { //后端服務(wù)器 靜態(tài)2
.host = "192.168.18.102";
.port = "80";
.probe = healthchk;
}
acl purgers { //定義允許清理緩存的IP
"127.0.0.0"/8;
"192.168.18.131"/32;
}
acl baner { //定義允許清理同一類的緩存的IP
"127.0.0.1"/8;
}
sub vcl_init { //創(chuàng)建后端服務(wù)器組
new websrvs = directors.round_robin(); //靜態(tài)組
websrvs.add_backend(websrv1);
websrvs.add_backend(websrv2);
new appsrvs = directors.round_robin(); //動態(tài)組
appsrvs.add_backend(appsrv1)色查;
}
sub vcl_recv {
if (req.url ~ "(?i)\.(jpg|jpeg|png|gif|svg|txt|html|css|js)$") { // 請求路徑中包含 圖片薯演,文本,js...格式的轉(zhuǎn)到后端靜態(tài)服務(wù)器組秧了,否則轉(zhuǎn)到動態(tài)服務(wù)器組
set req.backend_hint = websrvs.backup();
}else {
set req.backend_hint = appsrvs.backup();
}
if (req.url ~ "(?i)^/admin") { //請求路徑中含admin的直接不緩存跨扮,直接連向后端服務(wù)器
return(pass);
}
if (req.method == "PURGE") { //如果請求方法是PURGE,也就是裁剪緩存
if (!client.ip ~ purgers) {
return(synth(405,"Purging not allowed for " + client.ip)); //如果客戶端IP不在我們之前定義的ACL for purges中示惊,提示如下信息
}
return(purge);
}
if (req.method == "BAN") { //BAN請求的處理
if (!client.ip ~ baner) {
return(synth(405,"baning not allowed for " + client.ip));
}
ban("req.http.host == " + req.http.host + " && req.url == " + req.url);
return (synth(200,"Ban added"));
}
if (req.method == "PURGE") { // PURGE請求的處理
return(purge);
}
if (req.restarts == 0) { // #記錄客戶端ip
if (req.http.X-Fowarded-For) {
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + "," + client.ip;
} else {
set req.http.X-Forwarded-For = client.ip;
}
}
}
sub vcl_purge { //定義裁剪緩存的提示信息
return (synth(200,"Purged."));
}
if ( beresp.status != 200 && beresp.status != 404 ) { // 如果相應的狀態(tài)碼不是200或者404好港,則不緩存
set beresp.uncacheable = true;
set beresp.ttl = 120s;
return (deliver);
}
set beresp.ttl = 1h; //設(shè)置默認ttl緩存為 1小時
set beresp.grace = 30s; //意思在30s 內(nèi)復制舊的請求結(jié)果給客戶端
return (deliver);
}
sub vcl_deliver { // 為響應添加X-Cache首部,顯示緩存是否命中
if (obj.hits > 0) {
set resp.http.X-Cache = " Hit via " + server.ip; //提示沒有命中
} else {
set resp.http.X-Cache = " Miss via " + server.ip; // 提示有命中
}
}