6.2 VCL
Varnish配置
Varnish 的配置系統(tǒng)與其他軟件不同,一般的配置是使用配置指令,用于打開或關閉某個配置項。而 Varnish 使用 VCL 語言進行配置。
查看 varnish 服務的主配置文件
[root@CentOS74 ~]# cat /etc/varnish/varnish.params | grep ^[^#] RELOAD_VCL=1 #此值為1時可以在不重啟varnish的情況下加載vcl文件 VARNISH_VCL_CONF=/etc/varnish/default.vcl #vcl配置文件路徑 VARNISH_LISTEN_PORT=6081 #主進程監(jiān)聽端口,默認監(jiān)聽在0.0.0.0 VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 #命令行管理接口監(jiān)聽IP VARNISH_ADMIN_LISTEN_PORT=6082 #命令行管理接口監(jiān)聽端口 VARNISH_SECRET_FILE=/etc/varnish/secret #連接管理接口所需的秘鑰文件路徑 VARNISH_STORAGE="malloc,256M" #使用的緩存方式及所能使用的空間大小 VARNISH_USER=varnish #以誰的身份運行 VARNISH_GROUP=varnish #以哪個組的身份運行 DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300" #自定義運行時的選項,使用-p設定,可使用多次-
vcl語法
語法格式:
? ? 從varnish 4.0版本開始,每一個VCL文件都必須在文件開始處說明版本號VCL4.0
? ? //, # 單行注釋 /* ...?*/ 多行注釋
? ? sub 后跟子例程,例如sub vcl_recv { ...}
? ? 不支持循環(huán),受限于引擎的內建變量
? ? return() 函數使用關鍵字指定下一條引擎,用于實現狀態(tài)引擎轉換
? ? 引擎需要單獨定義
請求與請求之間是無關聯的
請求之間在被處理時是被隔離的
VCL中的子程序既不帶參數,也不返回值
VCL中的子程序只能通過HTTP頭交換數據
vcl 有許多默認配置,其內容無法修改。vcl 中的配置可以分為?Client Side 與?Backend Side
Client Side 中使用的引擎有:
? ??vcl_recv, vcl_pass, vcl_hit, vcl_miss, vcl_pipe, vcl_purge, vcl_synth, vcl_deliver
Backend Side 中使用的引擎有:
? ??vcl_backend_fetch, vcl_backend_response, vcl_backend_error
查看 vcl 默認配置
vcl 4.0; #開頭聲明使用的是vcl 4.0####################################################################### # Client side #面向客戶端側vcl的配置段sub vcl_recv {if (req.method == "PRI") { #如果請求方法時PRI/* We do not support SPDY or HTTP/2.0 */return (synth(405)); #narnish4.0不支持HTTP2.0協(xié)議,下一跳synth引擎并指定405響應碼}if (req.method != "GET" && #如果請求方法不是常規(guī)方法req.method != "HEAD" &&req.method != "PUT" &&req.method != "POST" &&req.method != "TRACE" &&req.method != "OPTIONS" &&req.method != "DELETE") {/* Non-RFC2616 or CONNECT which is weird. */return (pipe); #下一跳到pipe引擎}if (req.method != "GET" && req.method != "HEAD") { #如果不是GET或HEAD方法/* We only deal with GET and HEAD by default */return (pass); #下一跳到pass引擎}if (req.http.Authorization || req.http.Cookie) { #如果請求中包含敏感信息/* Not cacheable by default */return (pass); #下一跳到pass引擎}return (hash); #符合上面所有if語句,則使用hash引擎 }通過查看上面的默認 vcl 配置,可以總結出 vcl 的基本語法:
sub subroutine {... }if CONDITION {... } else {... }return(), hash_data()-
內建函數與關鍵字
函數
? ? regsub(str, regex, sub)? 正則匹配替換
? ? regsuball(str, regex, sub)? 正則匹配全局替換
? ? ban(boolean expression)??
? ? hash_data(input)? 數據hash計算
? ? synthetic(str)? 字符串處理
關鍵字
? ??call subroutine? 調用子例程
? ??return(action)? 返回值
? ??new? 新鍵對象
? ? set? 設置變量
? ? unset? 撤銷變量
操作符
比較操作符
? ? == , != , ~ , > , >= , < , <=
邏輯操作符
? ??&& , || , !
-
變量
內建變量
? ? req.* ?request? 表示由客戶端發(fā)來的請求報文相關
?? ??? ?req.http.*
?? ??? ??? ?req.http.User-Agent, req.http.Referer, ...
?? ?bereq.* ?由varnish發(fā)往BE主機的httpd請求相關
?? ??? ?bereq.http.*
?? ?beresp.* ?由BE主機響應給varnish的響應報文相關
?? ??? ?beresp.http.*
?? ?resp.* ?由varnish響應給client相關;
?? ?obj.* ?存儲在緩存空間中的緩存對象的屬性;只讀
常用變量
? ? bereq.*, req.* ?
?? ??? ?bereq.http.HEADERS
?? ??? ?bereq.request, req.request ?請求方法
?? ??? ?bereq.url, req.url ?請求的url
?? ??? ?bereq.proto ?請求的協(xié)議版本
?? ??? ?bereq.backend ?指明要調用的后端主機
?? ??? ?req.http.Cookie ?客戶端的請求報文中Cookie首部的值;
?? ??? ?req.http.User-Agent ~ "chrome"
?
? ? beresp.*, resp.* ?
?? ??? ?beresp.http.HEADERS
?? ??? ?beresp.status, resp.status ?響應的狀態(tài)碼
?? ??? ?reresp.proto, resp.proto ?協(xié)議版本
?? ??? ?beresp.backend.name ?BE主機的主機名
?? ??? ?beresp.ttl? 后端主機響應的內容的余下的可緩存時長
? ? obj.*
?? ??? ?obj.hits ?此對象從緩存中命中的次數
?? ??? ?obj.ttl ?對象的ttl值
? ? server.*
?? ??? ?server.ip ?varnish主機的IP
?? ??? ?server.hostname ?varnish主機的Hostname
?? ?client.*
?? ??? ?client.ip ?發(fā)請求至varnish主機的客戶端IP
網絡拓撲如下
-
緩存的修剪
Purge
purge 對請求的 url 進行清除
acl Admin {"192.168.30.174"/32; #定義管理主機組"192.168.30.74"; }sub vcl_recv {if (req.method == "PURGE") { #如果使用PURGE方法請求if (!client.ip ~ Admin) {return(synth(405,"Permission denied for " + client.ip)); #且對端IP屬于管理機組}return(purge); #則下一跳至purge引擎} }sub vcl_purge {return (synth(200,"Purged.")); }acl 定義訪問控制列表
acl 名稱 {"IP地址"[/子網掩碼];... }在測試的過程中,發(fā)現 varnish 在緩存時,會對整個 URL 進行 hash 計算,也就是說
curl http://192.168.30.75 curl http://192.168.30.75/index.html訪問的內容雖說一樣,但是在緩存時是兩條不同的記錄,但是
curl http://192.168.30.75 curl 192.168.30.75卻是同一條記錄
Banning
ban 規(guī)則推薦在命令行管理接口中使用,在配置文件中定義使用反而更加死板
在命令行管理接口中使用
? ? 語法:ban <field> <operator> <arg>
ban req.http.host ~ (?i)^192.168.30.74 #清除指定目標主機的緩存 200 ban req.url ~ (?i)^/index.html #清除指定URL的緩存 200在配置文件中使用
sub vcl_recv {if (req.method == "BAN") {ban("req.http.host == " + req.http.host + " && req.url == " + req.url);return(synth(200, "Ban added"));} }-
Varnish調度
varnish 作為一個緩存服務器,同時也是一臺代理服務器。所以同樣業(yè)具有向后端主機調度的功能。當后端主機有多臺時,就需要在varnish 中定義后端主機組,并根據使用場景規(guī)定調度算法。
Round_Robin
vcl 4.0; import directors; #在使用調度功能之前,必須事前聲明使用directors模塊backend server1 { #定義單個后端主機.host = "192.168.30.174";.port = "80"; }backend server2 {.host = "192.168.30.69";.port = "80"; }sub vcl_init { #在init引擎中新鍵組,并將后端主機加載進指定組中new webservers = directors.round_robin();webservers.add_backend(server1);webservers.add_backend(server2); }sub vcl_recv {set req.backend_hint = webservers.backend(); #在recv引擎中調用指定的組 } [root@CentOS75 ~]# for i in {1..10} ;do curl http://192.168.30.75/test$i.html ;done This is 174 test1 This is 69 test2 This is 174 test3 This is 69 test4 This is 174 test5 This is 69 test6 This is 174 test7 This is 69 test8 This is 174 test9 This is 69 test10Random
sub vcl_init { #在init引擎中新鍵組,并將后端主機加載進指定組中new webservers = directors.random(); #使用random調度算法webservers.add_backend(server1,2);webservers.add_backend(server2,1); } [root@CentOS75 ~]# for i in {1..10} ;do curl http://192.168.30.75/test$i.html ;done This is 174 test1 This is 174 test2 This is 174 test3 This is 174 test4 This is 174 test5 This is 174 test6 This is 174 test7 This is 69 test8 This is 174 test9 This is 69 test10基于cookie的session sticky
sub vcl_init {new webservers = directors.hash(); #聲明使用hash調度算法webservers.add_backend(server1,1);webservers.add_backend(server2,1); #基于hash的會話綁定也支持定義權重 }sub vcl_recv {set req.backend_hint = webservers.backend(req.http.cookie); #指定進行hash計算的目標 }-
健康狀態(tài)檢測
檢測的方法:
? ? url:檢測時要請求的URL,默認為”/";?
? ? request:發(fā)出的具體請求;
request =?"GET /.healthtest.html HTTP/1.1" #使用的方法與協(xié)議"Host: www.magedu.com" #請求的host"Connection: close" #短連接使用 backend.list 查看后端主機狀態(tài)
backend.list 200 Backend name Refs Admin Probe default(192.168.30.174,,80) 4 probe Healthy (no probe) server1(192.168.30.174,,80) 4 probe Healthy 5/5 server2(192.168.30.69,,80) 4 probe Sick 0/5? ? 語法:backend.set_health <backend_expression> <state>
? ? state:
sick:管理down
healthy:管理up
auto:probe auto
后端主機屬性
backend default {.host = "192.168.30.174";.port = "80";.connect_timeout = 0.5s; #連接超時時間.first_byte_timeout = 20s; #響應超時時間.between_bytes_timeout = 5s; #傳輸間隔超時時間.max_connections = 50; #最大并發(fā)連接書}?
?
總結
- 上一篇: 如何在计算机课堂中培养核心素养,如何在信
- 下一篇: SEO优化_关键词布局与选择