分佈式架構 Varnish優化

分佈式架構 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 啓動

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)

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章