1. 程式人生 > >緩存varnish配置詳解

緩存varnish配置詳解

varnish

一 工作原理

在當前主流的Web服務架構體系中,Cache擔任著越來越重要的作用。常見的基於瀏覽器的C/S架構,Web Cache更是節約服務器資源的關鍵。而最近幾年由FreeBSD創始人之一Kamp開發的varnish更是一個不可多得的Web Cache Server。嚴格意義上說,Varnish是一個高性能的反向代理軟件,只不過與其出色的緩存功能相比,企業更願意使用其搭建緩存服務器。同時,由於其工作在Web Server的前端,有一部分企業已經在生產環境中使用其作為舊版本的squid的替代方案,以在相同的服務器成本下提供更好的緩存效果,Varnish更是作為CDN緩存服務器的可選服務之一。

Varnish主要有以下幾點特性:

1.緩存位置:可以使用內存也可以使用磁盤。如果要使用磁盤的話推薦SSD做RAID1

2.日誌存儲:日誌也存儲在內存中。存儲策略:固定大小,循環使用

3.支持虛擬內存的使用。

4.有精確的時間管理機制,即緩存的時間屬性控制。

5.狀態引擎架構:在不同的引擎上完成對不同的緩存和代理數據進行處理。可以通過特定的配置語言設計不同的控制語句,以決定數據在不同位置以不同方式緩存。類似於netfilter中的鉤子,在特定的地方對經過的報文進行特定規則的處理。

6.緩存管理:以二叉堆格式管理緩存數據,做到數據的及時清理。




二 基本架構

1. 狀態引擎

技術分享圖片

2.內部處理流程

技術分享圖片




三 配置詳解

1. 簡單安裝

[root@node1?~]#?yum?install?varnish?-y

2. 配置詳解

[root@node1?~]#?cd?/etc/varnish

配置default.vcl配置文件

[root@node1?varnish]#?cat?default.vcl
#?使用varnish版本4的格式.
vcl?4.0;
#?加載後端輪詢模塊
import?directors;
#######################健康檢查策略區域###########################
#?名為www_probe的健康檢查策略
probe?www_probe?{
.request?=
"GET?/html/test.html?HTTP/1.1"????#?健康檢查url為/html/test.html?協議為http1.1
#"Host:?www.xiaxiaodie.com"????????#?訪問的域名為www.xiaxiaodie.com
"Connection:?close";????????#?檢查完關閉連接
#其他參數?如?超時時間?檢查間隔?等?均使用默認
}
##################################################################
#######################配置後端區域################################
backend?backend_15?{
.host?=?"172.18.67.15";
.port?=?"80";
.probe?=?www_probe;?#?使用名為www_probe的健康檢查策略
}
backend?backend_16?{
.host?=?"172.18.67.16"?
.port?=?"80";
.probe?=?www_probe;?#?使用名為www_probe的健康檢查策略
}
#默認後端
backend?default?{
.host?=?"172.18.67.15"?
.port?=?"80";
}
###################################################################
#?配置後端集群事件
sub?vcl_init?{
#?後端集群有4種模式?random,?round-robin,?fallback,?hash
#?random?隨機
#?round-robin?輪詢
#?fallback?後備
#?hash?固定後端?根據url(req.http.url)?或?用戶cookie(req.http.cookie)?或?用戶session(req.http.sticky)(這個還有其他要配合)
#?把backend_15?和?backend_16配置為輪詢集群?取名為www_round_robin
new?www_round_robin?=?directors.round_robin();
www_round_robin.add_backend(backend_15);
www_round_robin.add_backend(backend_16);
#?把backend_15?和?backend_16配置為隨機選擇集群?取名為www_random
new?www_random?=?directors.random();
www_random.add_backend(backend_15,10);??#?設置backend_15後端的權重為10
www_random.add_backend(backend_16,5);???#?設置backend_16後端的權重為5
#?把backend_15?和?backend_16配置為固定後端集群?取名為www_hash?在recv調用時還需要添加東西?看recv例子
new?www_hash?=?directors.hash();
www_hash.add_backend(backend_15,1);????????#?設置backend_15後端的權重為1
www_hash.add_backend(backend_16,1);????????#?設置backend_16後端的權重為1
}
#定義允許清理緩存的IP
acl?purge?{
#?For?now,?I‘ll?only?allow?purges?coming?from?localhost
"127.0.0.1";
"localhost";
}
#?請求入口?這裏一般用作路由處理?判斷是否讀取緩存?和?指定該請求使用哪個後端
sub?vcl_recv?{
#?域名為?www.xiaxiaodie.com?的請求?指定使用名為www_round_robin的後端集群??在集群名後加上?.backend()?如只使用單獨後端?直接寫後端名字即可?如?=?backend_16;
if?(req.http.host?~?"node2")?{
set?req.backend_hint?=?www_round_robin.backend();
}
#?使用固定後端集群例子?使用名為www_hash的集群
if?(req.http.host?~?"3g.xiaxiaodie.com")?{
set?req.backend_hint?=?www_hash.backend(req.http.cookie);??#?根據用戶的cookie來分配固定後端?可以指定其他分配規則
}
#?其他將使用default默認後端
#?把真實客戶端IP傳遞給後端服務器?後端服務器日誌使用X-Forwarded-For來接收
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.method?==?"PURGE")?{
#?如果發起請求的客戶端IP?不是在acl?purge裏面定義的?就拒絕
if?(!client.ip?~?purge)?{
return?(synth(405,?"This?IP?is?not?allowed?to?send?PURGE?requests."));
}
#?是的話就執行清理
return?(purge);
}
#?如果不是正常請求?就直接穿透沒商量
if?(req.method?!=?"GET"?&&
req.method?!=?"HEAD"?&&
req.method?!=?"PUT"?&&
req.method?!=?"POST"?&&
req.method?!=?"TRACE"?&&
req.method?!=?"OPTIONS"?&&
req.method?!=?"PATCH"?&&
req.method?!=?"DELETE")?{
/*?Non-RFC2616?or?CONNECT?which?is?weird.?*/
return?(pipe);
}
#?如果不是GET和HEAD就跳到pass?再確定是緩存還是穿透
if?(req.method?!=?"GET"?&&?req.method?!=?"HEAD")?{
return?(pass);
}
#?緩存通過上面所有判斷的請求?(只剩下GET和HEAD了)
return?(hash);
}
#?pass事件
sub?vcl_pass?{
#?有fetch,synth?or?restart?3種模式.?fetch模式下?全部都不會緩存
return?(fetch);
}
#?hash事件(緩存事件)
sub?vcl_hash?{
#?根據以下特征來判斷請求的唯一性?並根據此特征來緩存請求的內容?特征為&關系
#?1.?請求的url
#?2.?請求的servername?如沒有?就記錄請求的服務器IP地址
#?3.?請求的cookie
hash_data(req.url);
if?(req.http.host)?{
hash_data(req.http.host);
}?else?{
hash_data(server.ip);
}
#?返回lookup?,?lookup不是一個事件(就是?並非指跳去sub?vcl_lookup)?他是一個操作?他會檢查有沒有緩存?如沒有?就會創建緩存
return?(lookup);
}
#?緩存命中事件?在lookup操作後自動調用?官網文檔說?如沒必要?一般不需要修改
sub?vcl_hit?{
#?可以在這裏添加判斷事件(if)?可以返回?deliver?restart?synth?3個事件
#?deliver??表示把緩存內容直接返回給用戶
#?restart??重新啟動請求?不建議使用?超過重試次數會報錯
#?synth????返回狀態碼?和原因?語法:return(synth(status?code,reason))
#?這裏沒有判斷?所有緩存命中直接返回給用戶
return?(deliver);
}
#?緩存不命中事件?在lookup操作後自動調用?官網文檔說?如沒必要?一般不需要修改
sub?vcl_miss?{
#?此事件中?會默認給http請求加一個?X-Varnish?的header頭?提示:?nginx可以根據此header來判斷是否來自varnish的請求(就不用起2個端口了)
#?要取消此header頭?只需要在這裏添加?unset?bereq.http.x-varnish;?即可
#?這裏所有不命中的緩存都去後端拿?沒有其他操作?fetch表示從後端服務器拿取請求內容
return?(fetch);
}
#?返回給用戶的前一個事件?通常用於添加或刪除header頭
sub?vcl_deliver?{
#?例子
#?set?resp.http.*????用來添加header頭?如?set?resp.http.xiaxiaodie?=?"haha";?unset為刪除
#?set?resp.status?????用來設置返回狀態?如?set?resp.status?=?404;
#?obj.hits????????會返回緩存命中次數?用於判斷或賦值給header頭
#?req.restarts????會返回該請求經歷restart事件次數?用戶判斷或賦值給header頭
#?根據判斷緩存時間來設置xiaxiaodie-Cache?header頭
if?(obj.hits?>?0)?{
set?resp.http.xiaxiaodie_Cache?=?"cached";
}?else?{
set?resp.http.xiaxiaodie_Cache?=?"uncached";
}
#取消顯示php框架版本的header頭
unset?resp.http.X-Powered-By;
#取消顯示nginx版本、Via(來自varnish)等header頭?為了安全
unset?resp.http.Server;
unset?resp.http.X-Drupal-Cache;
unset?resp.http.Via;
unset?resp.http.Link;
unset?resp.http.X-Varnish;
#顯示請求經歷restarts事件的次數
set?resp.http.xiaxiaodie_restarts_count?=?req.restarts;
#顯示該資源緩存的時間?單位秒
set?resp.http.xiaxiaodie_Age?=?resp.http.Age;
#顯示該資源命中的次數
set?resp.http.xiaxiaodie_hit_count?=?obj.hits;
#取消顯示Age?為了不和CDN沖突
unset?resp.http.Age;
#返回給用戶
return?(deliver);
}
#處理對後端返回結果的事件(設置緩存、移除cookie信息、設置header頭等)?在fetch事件後自動調用
sub?vcl_backend_response?{
#後端返回如下錯誤狀態碼?則不緩存
if?(beresp.status?==?499?||?beresp.status?==?404?||?beresp.status?==?502)?{
set?beresp.uncacheable?=?true;
}
#如請求php或jsp?則不緩存
if?(bereq.url?~?"\.(php|jsp)(\?|$)")?{
set?beresp.uncacheable?=?true;
#php和jsp以外的請求
}?else?{
#如請求html?則緩存5分鐘
if?(bereq.url?~?"\.html(\?|$)")?{
set?beresp.ttl?=?300s;
unset?beresp.http.Set-Cookie;
#其他緩存1小時?如css?js等
}else{
set?beresp.ttl?=?1h;
unset?beresp.http.Set-Cookie;
}
}
#開啟grace模式?表示當後端全掛掉後?即使緩存資源已過期(超過緩存時間)?也會把該資源返回給用戶?資源最大有效時間為6小時
set?beresp.grace?=?6h;
#返回給用戶
return?(deliver);
}

配置varnish.params配置文件

[root@node1?varnish]#?vim?varnish.params
#?Varnish?environment?configuration?description.?This?was?derived?from
#?the?old?style?sysconfig/defaults?settings
#?Set?this?to?1?to?make?systemd?reload?try?to?switch?VCL?without?restart.
RELOAD_VCL=1
#?Main?configuration?file.?You?probably?want?to?change?it.
VARNISH_VCL_CONF=/etc/varnish/default.vcl
#?Default?address?and?port?to?bind?to.?Blank?address?means?all?IPv4
#?and?IPv6?interfaces,?otherwise?specify?a?host?name,?an?IPv4?dotted
#?quad,?or?an?IPv6?address?in?brackets.
#?VARNISH_LISTEN_ADDRESS=192.168.1.5
VARNISH_LISTEN_PORT=80
#?Admin?interface?listen?address?and?port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1
VARNISH_ADMIN_LISTEN_PORT=6082
#?Shared?secret?file?for?admin?interface
VARNISH_SECRET_FILE=/etc/varnish/secret
#?Backend?storage?specification,?see?Storage?Types?in?the?varnishd(5)
#?man?page?for?details.
VARNISH_STORAGE="malloc,256M"
#?User?and?group?for?the?varnishd?worker?processes
VARNISH_USER=varnish
VARNISH_GROUP=varnish
#?Other?options,?see?the?man?page?varnishd(1)
#DAEMON_OPTS="-p?thread_pool_min=5?-p?thread_pool_max=500?-p?thread_pool_timeout=300"

3.簡單管理工具

[root@node1?varnish]#?varnishadm?-S?secret?-T?127.0.0.1:6082
200????????
-----------------------------
Varnish?Cache?CLI?1.0
-----------------------------
Linux,3.10.0-327.el7.x86_64,x86_64,-smalloc,-smalloc,-hcritbit
varnish-4.0.4?revision?386f712
Type?‘help‘?for?command?list.
Type?‘quit‘?to?close?CLI?session.
help
200????????
help?[<command>]
ping?[<timestamp>]
auth?<response>
quit
banner
status
start
stop
vcl.load?<configname>?<filename>
vcl.inline?<configname>?<quoted_VCLstring>
vcl.use?<configname>
vcl.discard?<configname>
vcl.list
param.show?[-l]?[<param>]
param.set?<param>?<value>
panic.show
panic.clear
storage.list
vcl.show?[-v]?<configname>
backend.list?[<backend_expression>]
backend.set_health?<backend_expression>?<state>
ban?<field>?<operator>?<arg>?[&&?<field>?<oper>?<arg>]...
ban.list




四 訪問測試

[root@node1?varnish]#?systemctl?start?varnish.service

緩存varnish配置詳解