Varnish是一款高性能的開源HTTP加速器(其實就是帶緩存的反向代理服務),可以把http響應內容緩存到內存或文件中,從而提高web服務器響應速度。與傳統的 squid 相比,varnish 具有性能更高、速度更快、管理更加方便等諸多優點,很多大型的網站都開始嘗試使用 varnish 來替換 squid,這些都促進 varnish 迅速發展起來
Varnish程序結構
管理進程:編譯VCL并應用新配置、監控varnish、初始化varnish,并提供一個CLI,初始化緩存的內存結構,對緩存內存結構實現分成各個類型大小的內存塊。
Child/Cache線程有幾類:
Acceptor:接收新的連接請求;
Worker:用于處理并響應用戶請求;
Expiry:從緩存中清理過期cache object
日志:Shared Memory Log, 共享內存內存日志大小一般90MB;分為兩部分:前一部分為計數器、后一部分為客戶請求相關的數據。
對varnish內的緩存數據的有效管理:
Expires:定義一個緩存時長,過了緩存時長就認為緩存失效。
http validation
If-Modified-Since/Last Modified : 每次客戶端請求緩存內容,varnish會向后端主機詢問這個緩存對象自它緩存的時間開始時有沒有改變,沒改變的話會返回一個304,證明可以返回varnish內的緩存內容,如果改變了,需要向后端請求該內容返回給客戶端。
If-None-Match/Etag:會對varnish的緩存內容一個標簽和一個緩存時間,過了這個時間,向后端主機詢問這個緩存內容的標簽是否有改變,沒改變的話這個緩存內容增加其緩存時間。
Vcl內置函數和處理流程(狀態引擎)
Vcl內置函數:vcl配置的緩存策略在此些內置函數發揮作用;
vcl_recv:用于接受和處理請求。當請求到達并成功接收后被調用,通過判斷請求的數據來決定如何處理請求。例如如何響應、怎么響應、使用哪個后端服務器等。
vcl_fetch:根據服務器端的響應作出緩存決策,如判斷獲取的內容來決定是將內容放入緩存,還是直接返回給客戶端。
vcl_pipe:對于無法理解的用戶請求,將請求直接發往后端主機;
vcl_hash:自定義hash生成時的數據來源
vcl_pass:用于將請求直接傳遞至后端主機,后端主機在應答數據后將應答數據發送給客戶端,但不進行任何緩存。
vcl_hit:從緩存中查找到緩存對象時要執行的操作;
vcl_miss:從緩存中款查找到緩存對象時要執行的操作;
vcl_deliver:將用戶請求的內容響應給客戶端時用到的方法;
vcl_error:在varnish端合成錯誤響應而時;
vcl的配置語法:
(1) //, #, /*comment*/用于注釋;
(2) sub $NAME 用于定義函數;
(3) 不支持循環;
(4) 有眾多內置變量;
(5) 支持終止語句,沒有返回值;
(6) “域”專用語言;
(7) 操作符: =, ==, ~, !, &&, ||
常用變量:
1、在任何引擎中均可使用:
Now:獲取當前系統當前時間
.host:獲取當前主機名和ip地址
.port:后端服務器名稱和端口
2、用于處理請求階段:
client.ip,server.hostname, server.ip, server.port :都不解釋
req.request:請求方法
req.url:請求的URL
req.proto:HTTP協議版本
req.backend:用于服務此次請求的后端主機;
req.backend.healthy:后端主機健康狀態;
req.http.HEADER:引用請求報文中指定的首部;
req.can_gzip:客戶端是否能夠接受gzip壓縮格式的響應內容;
req.restarts:此請求被重啟的次數;
3、varnish向backend主機發起請求前可用的變量
bereq.request:請求方法
bereq.url:請求url
bereq.proto:HTTP協議版本
bereq.http.HEADER:調用服務此次請求的后端主機的報文首部
bereq.connect_timeout:等待與beckend建立連接的超時時長
4、backend主機的響應報文到達本主機(varnish)后,將其放置于cache中之前可用的變量
beresp.do_stream:流式響應(接收一個請求,響應一個請求)
beresp.do_gzip:是否壓縮之后再存入緩存;
beresp.do_gunzip:如果從后端收到壓縮格式的報文,是否解壓縮在存放下來
beresp.http.HEADER:獲取httpd的首部信息
beresp.proto:HTTP協議版本
beresp.status:響應狀態碼
beresp.response:響應時的原因短語
beresp.ttl:響應對象剩余的生存時長,單位為秒鐘;
beresp.backend.name:此響應報文來源backend名稱;
beresp.backend.ip:獲取后端響應ip
beresp.backend.port:獲取后端響應端口
beresp.storage:強制varnish將緩存存儲到緩存后端
5、緩存對象存入cache之后可用的變量
obj.proto:響應時使用的協議
obj.status:響應時使用的狀態碼
obj.response:服務器返回響應報文的狀態碼
obj.ttl:緩存對象生存時長
obj.hits:緩存對象被用作響應時的次數
obj.http.HEADER:調用對應的響應報文
6、在決定對請求鍵做hash計算時可用的變量
req.hash:指明把什么作為hash的鍵,作為緩存的鍵
7、在為客戶端準備響應報文時可用的變量
resp.proto:指明使用什么協議響應
resp.status:執行響應狀態嗎
resp.response:返回響應的狀態碼
resp.http.HEADER:調用響應報文狀態碼
變量在各狀態引擎使用情況:
varnish配置實例:
/etc/sysconfig/varnish 是定義varnish運行特性的配置文件;
/etc/varnish/default.vcl 是定義varnish的默認狀態引擎的工作配置文件(使用vcl語言定義)
(1)定義varnish后端多主機的實例:
backend bs1 {
.host = "www2.bwei.com";
.port = "80";
}
backend bs2 {
.host = "www3.bwei.com";
.port = "80";
}
director bs random {
{ .backend = bs1; .weight=1; }
{ .backend = bs2; .weight=2; }
}
sub vcl_recv {
if (req.url ~ "index.html"){
set req.backend = bs;
}
}
這里的director是實現調度器的角色,實現把兩個后端server合在一起,配置他們的權值及后端server的調度方式,這里有一重點,我們定義了后端server要在vcl_recv這個函數中調用,即定義那個資源要調配到那個后端server上。
(2)實現給客戶端的響應報文中,增加一個首部,給用戶看是否緩存命中。
sub vcl_deliver{
if (obj.hit >0){
set resp.http.X-cache = "hit via"+" "+server.hostname;
}else{
set resp.http.X-cache = "miss via"+" "+server.hostname;
}
}
(3)實現讓某些主機可以刪除varnish主機上的緩存:
acl purgers {
127.0.0.1;
192.168.179.0; /24
}
sub vcl_recv{
if (client.ip !~ purgers && req.request == "PURGE"){
error 405 "method not allowed";
}
return (lookup);
}
sub vcl_hit{
if (req.request == "PURGE"){
purge;
error 200 "cache has purge";
}
}
sub vcl_miss{
if(req.request == "PURGE"){
purge;
error 404 "not in cache";
}
sub vcl_pass{
if(req.request == "PURGE"){
error 502 "purge object not allowed in pass"
}
}
實現給varnish解析不了的方法,送到pipe上:
if ( req.request != "GET"&&
req.request != "HEAD"&&
req.request != "PUT"&&
req.request != "POST"&&
req.request != "TRACE"&&
req.request != "OPTIONS"&&
req.request != "DELETE"&&
req.request != "PURGE" ){ return (pipe);
實現讓除GET,HEAD,PURGE的方法可以到達hash狀態引擎,其余到達pass引擎
if (req.request != "GET" && req.request != "HEAD" && req.request != "PURGE"){
return (pass);
}
從后端主機獲取資源后,設定其緩存時間和不緩存cookie信息
sub vcl_fetch{
set beresp.ttl = 15s;
if (beresp.http.Set-Cookie){
return (pass)
}
return (deliver);
}
從后端主機獲取資源后,設置那些不能緩存的數據不進行緩存
sub vcl_fetch{
if(!beresp.cacheable){
return (pass);
}
if(beresp.http.Pragma ~"no-cache" ||
beresp.http.Cache-Control ~ "no-cache" ||
beresp.http.Cache-Control ~ "private"){
return (pass);
}
}
設置客戶端請求我們的varnish出現認證和cookie時,把它們直接送去pass引擎
if(req.http.Authorization || req.http.Cookie){
return (pass);
}
設置對后端主機進行健康狀態檢查:
probe healthcheck {
.url = "/health.html";
.interval = 60s;
.timeout = 0.3s;
.window = 8;
.threshold = 3;
.initial = 3;
.expected_response = 200;
}
backend bs1 {
.host = "www2.bwei.com";
.port = "80";
.probe = healthcheck;
}
backend bs2 {
.host = "www3.bwei.com";
.port = "80";
.probe = healthcheck;
}
varnish的配置段需要我們對其進行編譯才能運行,我們對其每次對其進行改變都需要重新編譯和使用:
varnishadm管理軟件可以實現vcl語言編譯:vcl.load <name> <filename>(加載vcl配置)
vcl.use <name> (使用vcl配置)
原創文章,作者:13-廣州-楊過,如若轉載,請注明出處:http://www.www58058.com/9551
圖很專業,代碼如何能格式化配合一定樣式就是精品了