緩存varnish配置詳解
阿新 • • 發佈:2017-12-11
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配置詳解