分佈式架構 Varnish優化
Varnish優化
- 核心優化,通過VCL優化配置
- 通過硬件負載均衡到多臺varnish分流
Varnish介紹
-
Varnish一款開源的、高性能HTTP加速器和反向代理服務器
-
Varnish主要通過緩存來實現web訪問加速
-
Varnish主要基於內存進行緩存、支持精確緩存時效,性能高效
其 VCL配置管理比較靈活,支持後端服務器負載和健康檢查,內部實現負載均衡輪詢調用服務器 -
varnish主要由兩個進程,管理進程和子進程
管理進程主要負責(配置變更、編譯VCL、監控運行、初始化),定期檢查子進程、子進程掛了會kill後重新開啓。
子進程包括(worker線程、aceptor線程、expiry線程清除舊內容),使用workspace工作區來減少多個線程間對於內存的競爭
Varnish 安裝
- 安裝gcc
- 安裝pcre 正規表達式
- 安裝libedit-dev yum install libedit-dev*
https://www.varnish-cache.org/ 下載,解壓源碼,進入包根目錄 (tar zxvf varnish-3.0.5.tar.gz),安裝pcre後需要設置路徑 cd varnish-3.0.5
export PKG_CONFIG_PATH=/usr/local/pcre/lib/pkgconfig
配置varnish屬性文件到指定路徑
./configure --prefix=/usr/common/varnish
編譯/安裝
make、make install
安裝完後關掉防火牆
/sbin/service iptables stop
Varnish 啓動
- 核心配置 default.vcl /etc/varnish目錄
- cd /varnish/sbin/
- 運行./varnished -f /usr/common/varnish/etc/varnish/default.vcl -s malloc,32M -T 127.0.0.1:2000 -a 0.0.0.0:2222
-s malloc 存儲類型和容量
-T 127.0.0.1:9000 指定管理ip和端口
-a 0.0.0.0:2222 對外界提供web服務的ip和端口
運行demo
http://192.168.0.102:2222/zachary/demo/showtime 通過varnish代理
http://192.168.0.102:9021/zachary/demo/showtime 直接訪問tomcat
Varnish 關閉
- cd /varnish/sbin
- 運行pkill varnished
Varnish 結構圖
核心配置default.vcl講解
probe tz1{
.url="/demo/xxxx.index.html";//檢查後端健康頁面
.timeout=0.3s;//過期時間
.window=8;//檢查後端服務次數
.threshod=3;// 檢查後端8次訪問,成功3次認爲是存活的
.initial=3;//varnish啓動,確保多少個probe正常
.expected_response=200; //期望expected code,默認是200
.interval=6;//定義probe多久檢查一次後端,默認5s
}
backend zachary{
.host="127.0.0.1";
.port="2222";
.connect_timeout=1s;
.first_byte_timeout=5s;
.between_byte.timeout=2s;
.max_connections=1000;
.probe=tz1;
}
backend resource{
.host="127.0.0.1";
.port="8099";
.connect_timeout=1s;
.first_byte_timeout=5s;
.between_byte.timeout=2s;
}
director zachary random{ //隨機
.retries=5;//查找可用後端次數
{
.backend=zachary;//引用已存在backend
.weight=6;
}
{
.backend=resource;//引用已存在backend
.weight=2; //類似nginx 權重
}
{
.backend={//定義新的backend
}
.weight=2;
}
}
director zachary round-robin{ //輪詢
{
.backend=zachary;//引用已存在backend
}
{
.backend=resource;//引用已存在backend
}
{
.backend={//定義新的backend
}
}
}
#權限訪問控制列表
acl purgeallow {
"127.0.0.1";
!"192.168.0.102"
}
sub vcl_recv{
if(!req.backend.healthy){
set req.grace=30m;//varnish緩存時間+50分鐘返回給客戶端
}else{
set req.grace=5s;
}
if(req.request== "PURGE"){
(!client.ip ~ purgeallow){
error 405 "not allowed";
}
return(lookup);
}
if(req.http.host ~ "^(www.)?zachary.cn$"){
set req.backnd=zachary1;
}
if(req.request== "GET" req.url ~ "\.(jpg|png|gif|swf|flv|ico|jpeg)$"){
unset req.http.cookie;
}
if(req.request== "GET" req.url ~ "(?i)\.jsp($|\?)"){
set req.backnd=resource;
return pass(pass);
}
}
sub vcl_fetch{
set beresp.grace=30m;//後端服務器返回varnish緩存時間+50分鐘
if(req.request== "GET" req.url ~ "\.(jpg|png|gif|swf|flv|ico|jpeg)$"){
set beresp.ttl=1d;
}
if(req.url ~ "^.*/zachary/demo/.*"){
set beresp.ttl=1d;
return(deliver);
}
}
sub vcl_hit{
std.log("url hit,your need to check it; it's url ="+req.url);
if(req.request=='PURGE'){
set obj.ttl=0s;//清除緩存
error 200 "Purged.";
}
return(fetch);
}
sub vcl_miss{
std.log("url miss,your need to check it; it's url ="+req.url);
if(req.request=='PURGE'){
error 200 "Purged.";
}
return(fetch);
}
參數講解
- backend 可以配置多個,1個請求對應1個backnd,裏面配置連接後端服務,connect_timeout連接後端超時時間,first_byte_timeout傳輸第一個字節時間,between_byte.timeout第二個和第一個中間傳輸時間,max_connections連接後端服務最大限制數
- 可以單獨配置多個backend,可以配置單個backend分發多個策略如(隨機、循環、DNS參考 以上director配置)
- probe配置健康檢查
- acl權限列表設置,可配置相關ip
- Grace模式
1.當多個客戶端請求同時訪問一個頁面。varnish只會發送一次請求到達後端,其它請求會被掛起等待返回結果,體驗不好
2.服務器請求流量高,比如秒殺、數千萬點擊率等。用戶不可能掛起等待結果
3.針對以上問題,varnish提供了Grace模式延長緩存失效時間,上次過期數據結果在失效時間之後延期多長時間,時間需根據系統斟酌設置
當後端服務器出現問題,負載過高後,varnish不訪問後端直接返回舊緩存數據給客戶端; - VCL返回策略
return(pass)//不緩存,直接調用服務器
return(lookup)//先從緩存獲取,沒有數據再從服務器獲取
return(pipe)當前連接未關閉前,所有的請求都直接請求服務器,varnish不處理
return(deliver)請求目標被緩存,然後返回給客戶端
Varnish優化手段
- varnish默認緩存策略很保守,默認只緩存GET、head請求,不緩存帶cookie和認證信息請求,可以更改配置調整
- 提搞varnish命中,可以仔細規劃請求和應答,並自定義緩存策略,通過VCL緩存自己想緩存內容,並主動設置對象過期時間,儘量不依賴http header
- 查看日誌varnishtop -i txurl,請求後端url,對比策略,讓需要緩存url緩存,不需要緩存剔除
- backend 超時時間需要根據應用情況適當調整
- 通過日誌輔助分析 varnish -I log,分析哪些希望命中卻沒有命中緩存連接
Varnish問題列表分析
- 1.Varnish需要緩存哪些內容?分析思考
- 2.Varnish緩存多少大小?分析思考
- 3.後端發生變化後,如何主動通知Varnish更新緩存?
- 4.Nginx和Varnish如何一起使用?
針對以上問題筆者分析結果
問題1
- 所有請求,按照應用模塊一塊塊分析,靜態資源和動態資源
- 動態資源可以緩存(一部分放到CDN,一部分可以緩存在varnish)
- 動態內容 大部分不會變動、少部分會變動,可以緩存部分內容
- 動態內容 有些業務實時需要處理數據,不能緩存的
問題2
- 應用熱門數據有多大?
- 用戶使用點擊率最高 如 首頁、連接出去相關頁面 需要緩存,大小?
- 緩存對象分類,如圖片、靜態頁面、數據集合,根據分類預估大小?
- 使用varnishstat監控工具,監控其內存使用情況?
- varnish每個對象額外開銷是1k,如果緩存中有很多小對象,花銷很大
問題3
- 如果是人工非程序更新內容,可以到varnish後臺管理把相關url清除掉,下次會重新獲取內容
curl -x PURGE http://localhost:8080/demo/query - 如果是程序自動更新服務端內容,方案如下
1.varnish提供PURGE清除緩存接口,程序方可以遠程調用接口清除緩存
2.書寫shell腳本,程序方調用shell腳本,傳入需要清除url,shell腳本主動調用varnish的admin後臺管理清除,程序和腳本需要自寫
問題4
- nginx (動靜)所有內容反向代理到varnish,varnish根據緩存策略,獲取緩存或者反向代理到tomcat獲取數據 返回客戶端
- nginx存儲靜態資源,動態內容代理到varnish獲取
筆者建議使用第二種,畢竟代理一次到varnish以及返回到nginx需要網絡傳輸。
總結:
- 優先使用瀏覽器緩存,如瀏覽器未緩存到,考慮結合使用Nginx和Varnish,取長補短,高效設置緩存策略,使用varnish之前優先考慮以上問題,進行提前規劃方案後再使用。筆者建議針對系統複雜情況綜合考慮使用
作者簡介:張程 技術研究
更多文章請關注微信公衆號:zachary分解獅 (frankly0423)