五、varnish的使用
(一)初步使用
1、編輯varnish的配置腳本文件:
從文件中可以看出,對進程的資源限制基本上都是被打開了,不做限制
如果要使用內存做緩存存儲類型,則須按下面修改配置文件:
VARNISH_STORAGE_SHM=64M
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}"(刪除或註釋掉原來的存儲類型配置)
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SHM}" (添加內存存儲類型配置)
爲了能夠更靈活地配置配置文件,其他配置都使用/etc/varnish/default.vcl來配置,二不用命令行工具varnishadm
2、定義好varnish工作特性配置文件後,就可以啓動varnish服務了:
[root@aunt-s ~]# service varnish start Starting Varnish Cache: [ OK ]
監聽的端口有三個,6082是管理接口的監聽端口,80是對遠程客戶端提供服務的監聽端口:
[root@aunt-s ~]# ss -tnlp | grep varnish LISTEN 0 10 127.0.0.1:6082 *:* users:(("varnishd",6033,6)) LISTEN 0 128 :::80 :::* users:(("varnishd",6034,8)) LISTEN 0 128 *:80 *:* users:(("varnishd",6034,7))
3、修改配置文件與varnishadm結合使用更換緩存存儲策略
node2主機配置httpd服務:
# yum install -y httpd Installed: httpd.x86_64 0:2.2.15-39.el6.centos Complete! [root@aunt-s ~]# vim /var/www/html/index.html <h1> web1</h1> [root@aunt-s ~]# service httpd start Starting httpd: [ OK ]
varnish主機也能獲取node2主機的web網頁:
[root@aunt-s ~]# curl 172.16.20.200 <h1> web1</h1>
配置文件:
修改後端監聽地址由127.0.0.1改爲提供web服務的主機地址,其他的暫時不需要改動
[root@aunt-s ~]# vim /etc/varnish/default.vcl backend default { .host = "172.16.20.200"; .port = "80"; } [root@aunt-s ~]# service varnish restart Stopping Varnish Cache: [FAILED] Starting Varnish Cache: [ OK ]
連接到varnish的CLI:
[root@aunt-s ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 …… varnish> ping 200 PONG 1433559864 1.0
有PONG迴應,表示服務器處於正常狀態。
輸入help能給出顯示所有可用的命令:
varnish> help 200 help [command] ping [timestamp] ——測試服務器是否處於正常狀態 auth response quit banner ——顯示banner信息 status ——顯示狀態信息 start ——啓動子進程 stop ——停止子進程 vcl.load <configname> <filename> ——裝載編譯配置文件爲一個vcl,取名爲configname vcl.inline <configname> <quoted_VCLstring> vcl.use <configname> ——使用configname的配置 vcl.discard <configname> ——刪除configname配置 vcl.list ——顯示所有可用的vcl vcl.show <configname> ——顯示對應configname的vcl (active)的配置 param.show [-l] [<param>] param.set <param> <value> panic.show panic.clear storage.list backend.list backend.set_health matcher state ban.url <regexp> ban <field> <operator> <arg> [&& <field> <oper> <arg>]... ban.list
緩存功能測試:
①、添加虛擬主機,提供httpd服務:
[root@node1 ~]# yum install -y httpd [root@node1 ~]# vim /var/www/html/index.html <h1>web1</h1>
②、修改varnish配置文件,使緩存的服務器內容指向新主機node1的web1
[root@aunt-s ~]# vim /etc/varnish/default.vcl backend default { .host = "172.16.20.150"; .port = "80"; }
③、在varnish主機上編譯配置文件,並啓用
[root@aunt-s ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load test1 default.vcl 200 VCL compiled. varnish> vcl.use test1 200
⑤、查看緩存配置效果
從上面的過程可以看出,varnish的使用流程是:
安裝varnish後會生成兩類(兩個)主要配置文件:一種是定義varnish程序自己的工作特性的配置文件,地址爲/etc/sysconfig/varnish ,一種是配置varnish如何爲需要緩存的服務器工作的配置文件/etc/varnish/default.vcl。
安裝varnish、varnish-libs--> 修改/etc/sysconfig/varnish ,定義好varnish自己的工作狀態,爲向其他服務器提供服務做好準備 --> 在需要緩存的服務器準備好後,修改/etc/varnish/default.vcl ,設定緩存工作的策略 --> 通過varnishadm CLI命令進行 vcl.load編譯,vcl.use使用,平滑非重啓式切換緩存工作策略(即原來的緩存不會立即失效,而是正常的過期失效並更換 --> 修改緩存策略,varnishadm編譯使用……
六、varnish的深入使用
(一)sub 子程序及if條件判斷:
[root@aunt-s ~]# vim /etc/varnish/default.vcl sub vcl_hit { if (obj.hits>0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } return (deliver); }
上面語句的意思是:如果某個緩存的命中數大於0,則設定內置變量resp.http.X-Cache的值爲 “HIT”,否則其值爲“MISS”。判斷處理完後轉到deliver引擎構建響應報文。
[root@aunt-s ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load test2 default.vcl 106 Message from VCC-compiler: 'resp.http.X-Cache': cannot be set in method 'vcl_hit'. At: ('input' Line 71 Pos 21) set resp.http.X-Cache = "HIT"; --------------------#################--------- Running VCC-compiler failed, exit 1 VCL compilation failed
如果配置文件出現了錯誤,則vcl.load時會報錯,這時重新修改配置文件即可
[root@aunt-s ~]# vim /etc/varnish/default.vcl sub vcl_deliver { if (obj.hits>0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } return (deliver); } [root@aunt-s ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load test2 default.vcl 200 VCL compiled. varnish> vcl.use test2 200 varnish> vcl.list 200 available 0 boot available 0 test1 active 2 test2
vcl.list查看可用的vcl,現在使用的緩存策略是test2
從上面的簡單例子裏可以看出,varnish的重點是在配置緩存工作策略,而緩存策略的配置是在各引擎中設定的。設定時就是使用條件判斷語句進行判斷後,設定各種內置的變量,從而通過這些變量進行工作。
可使用的條件判斷語句有:
單分支:
if (CONDITION) {
...;
}
雙分支:
if (CONDITION) {
...;
} else {
...;
}
多分支:
if (CONDITION1) {
...
} elseif (CONDITION2) {
...
} else {
...
}
if(obj.hits>0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache= "MISS";
}
可使用的變量有:
1、全局變量global variables:
now:現在的時間,單位是秒,從新紀元開始算起。可以用字符串上下文限定格式
2、backend declaration聲明中可用變量:
.host:後端服務器的主機名或者IP地址
.port:後端服務器提供的服務名或者端口號
3、處理請求時(recv、hash、pass、pipe)可用變量:
(縮進的表示不是特別重要的變量)
client.ip:客戶端的IP地址
client.identity:客戶端標識符,用於客戶調度時的負載均衡。(一般現在用不上)
server.hostname:varnish服務器的主機名
server.identity:varnish服務器的標識符,可通過-i設定,如果沒有通過-i設定,則會在通過-n設定
servier.ip:與客戶端建立連接時所使用的套接字中的IP地址
server.port:與客戶端建立連接時所使用的套接字中的端口號
req.request:請求類型,如GET、HEAD
req.url:被客戶端請求的url
req.proto:客戶端請求所使用的HTTP協議版本
req.backend:需要後端響應請求時所使用的後端主機,一般在recv中就設置好了
req.backend.healthy:後端服務器是否處於健康狀態,只有設置了健康探測動作後這個變量纔有使用的意義
req.http.HEADER:引用請求報文中指定的首部的值,如req.http.host表示引用請求報文首部host(服務器主機名)的值
req.hash_always_miss:是否強迫對此請求做緩存miss處理,如果設定值爲“true”,則varnish每次都會忽略緩存內容,而直接到後端服務器獲取信息
req.hash_ignore_busy:當查找緩存時忽略繁忙的緩存內容而不去查詢
req.can_gzip:客戶端是否接受gzip壓縮編碼格式的報文
req.restarts:此請求被重啓的次數(url改寫引起。當重啓次數高於一定值時,varnish內生機制會放棄此次請求的緩存查詢)
req.grace:設定寬限期的值
4、向後端服務器發起請求時常用的變量(本地無緩存或pass、pipe模式時使用)
bereq.request:請求的類型,如GET、HEAD
bereq.url:請求的url
bereq.proto:與後端服務器通信時使用的HTTP協議版本
bereq.http.HEADER:向後端服務器發請求時調用我們感興趣的首部,與處理客戶端請求時類似
bereq.connect.timeout:等待與後端建立連接的超時時長,單位爲秒,發出建立連接請求後多少秒還沒有收到建立連接的響應就不會再等待迴應
還有其他變量,但不常用,一般都不設置,這裏就不列了
5、從後端服務器請求的對象取回但還沒有存入本次緩存時可用的變量(這時還沒有構建響應報文),也即是在vcl_fetch中可用的變量:
beresp.do_stream:從後端接收到報文後直接將其封裝響應給客戶,而不是在接收到本次請求的所有響應報文後再封裝響應給客戶。當後端響應報文有10M時這個選項特別有效。
beresp.do_gzip:布爾型值(值爲yes|no),收到後端響應的對象後是否先壓縮再存儲在緩存,如果壓縮了,而客戶端瀏覽器識別不了gzip編碼格式的報文,則客戶端是無法獲得請求網頁或數據的。默認爲no
beresp.do_gunzip:布爾型值(值爲yes|no),收到後端響應的對象後是否先解壓縮再存儲在緩存,解壓縮是爲了不能接受gzip壓縮的客戶端時可用使用的,如果客戶端指定了要gzip編碼格式的報文,則不應該解壓縮。默認爲no
beresp.http.DEADER:響應報文的特定頭部
beresp.proto:後端服務器響應時所使用的HTTP協議版本
beresp.status:後端服務器響應給varnish的HTTP狀態碼,200,404等
beresp.response:後端服務器響應給varnish的HTTP狀態原因短語
beresp.ttl:響應對象的剩餘的生存時長,單位爲秒,此值可修改
beresp.backend.name:發送此次響應報文的後端服務器的主機名
beresp.backend.ip:發送此次響應報文的後端服務器的IP
beresp.backend.port:發送此次響應報文的後端服務器的端口
beresp.storage:強制varnish將此對象緩存存儲到特定的存儲後端,用得不多
6、緩存對象存入cache之後可用的變量(在vcl_hit或vcl_error中使用,大部分只讀):
obj.proto:緩存對象取回時所使用的HTTP協議版本
obj.status:後端服務器響應此緩存對象的狀態碼
obj.response:後端服務器響應此緩存對象的狀態碼的原因短語
obj.ttl:此緩存對象剩餘生存時長,單位爲秒,可修改
obj.hits:此緩存的已經被髮送給客戶端的次數的近似值(即命中次數),0表示無命中,在vcl_deliver中也可用
obj.http.HEADER:來自於後端服務器的響應報文的指定頭部的值
7、在決定對請求鍵做hash計算時可用的變量
req.hash:指向某個緩存對象的hash key,在從緩存中讀和向緩存中寫時需要用到
8、在爲客戶端準備響應報文時可用的變量(vcl_deliver中使用)
resp.proto:構建響應報文時使用的HTTP協議版本
resp.status:構建響應報文時響應給客戶端的狀態碼
resp.response:構建的響應報文的狀態碼的原因短語
resp.http.HEADER:構建的響應報文的特定頭部
9、用於對後端主機健康狀態監測使用的變量:
.probe中的探測指令常用的有:
(1) .url:指定探測後端主機健康狀態時請求的URL,默認爲“/”;
(2) .request: 探測後端主機健康狀態時所請求內容的詳細格式,.request中定義的路徑優先級高於.url中定義的路徑,因此定義後,它會替換.url指定的探測方式;比如:
.request =
"GET /.healthtest.html HTTP/1.1"
"Host: www.magedu.com"
"Connection: close";
(3) .window:設定在判定後端主機健康狀態時基於最近多少次的探測進行,默認是8;
(4) .threshold:門檻數,在.window中指定的次數中,至少有多少次是成功的才判定後端主機正健康運行;默認是3;
(5) .initial:Varnish啓動時對後端主機至少需要多少次的成功探測,默認同.threshold;
(6) .expected_response:期望後端主機響應的狀態碼,默認爲200;
(7) .interval:探測請求的發送週期,設置得過長,移除故障後端的時間就越長,默認爲5秒;
(8) .timeout:每次探測請求的過期時長,默認爲2秒;
(二)應用實例
1、vcl_recv子進程的啓用及客戶ip的傳送:
vcl_recv子進程是接受報文的第一站,重要引擎調度及分配是在這一子進程設置得。
啓用vcl_recv子進程前訪問日誌未記錄客戶端地址,而全是緩存服務器地址:
[root@node1 ~]# tail -3 /var/log/httpd/access_log 172.16.20.100 - - [06/Jun/2015:20:18:37 +0800] "GET / HTTP/1.1" 200 14 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36" 172.16.20.100 - - [06/Jun/2015:20:18:37 +0800] "GET /favicon.ico HTTP/1.1" 404 288 "http://172.16.20.100/" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36" 172.16.20.100 - - [06/Jun/2015:20:56:19 +0800] "GET / HTTP/1.1" 200 23 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36"
修改配置文件,啓用sub vcl_recv子進程的內容、後端服務器不變:
[root@aunt-s ~]# vim /etc/varnish/default.vcl backend default { .host = "172.16.20.150"; .port = "80"; } sub vcl_recv { 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.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.request != "GET" && req.request != "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); } return (lookup); }
[root@aunt-s ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load t1 default.vcl 200 VCL compiled. varnish> vcl.use t1 200 varnish>
然後修改後端服務器日誌記錄格式並重載配置:
[root@node1 ~]# vim /etc/httpd/conf/httpd.conf LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined CustomLog logs/access_log combined [root@node1 ~]# service httpd reload Reloading httpd:
強制刷新網頁後查看後端服務器日誌:
2、禁止某個IP客戶端訪問(以172.16.250.248爲例)
修改配置文件,在sub vcl_recv段的return (lookup);語句之前添加如下條件控制語句:
sub vcl_recv { if (client.ip == "172.16.250.248") { error 404 "You are Forbidden!"; } return (lookup); }
[root@aunt-s ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load t2 default.vcl 200 VCL compiled. varnish> vcl.use t2 200 varnish>
3、sub vcl_hash說明:
先對請求的url做 hash計算,然後做條件判斷:
如果請求報文中的服務器主機名不爲空,則對該主機名進行hash計算;否則對varnish服務器的ip地址做hash計算。最後返回重新做hash模式。
一般情況下都不需要啓用這項子進程,讓系統採用默認配置就行
sub vcl_hash { hash_data(req.url); if (req.http.host) { hash_data(req.http.host); } else { hash_data(server.ip); } return (hash); }