varnish 簡介
css
varnish是一款強大的http加速器,其設計初衷由於計算機愈來愈複雜,不像那個只有內存與硬盤的存儲媒介的年代,現在的計算機系統除了內存外還有cpu的L一、L二、L3快取,所以當初的Squid cache自行處理物件替換的架構不可能得知這些狀況而作到最佳,但操做系統能夠得知該狀況,此PoulHenning Kamp設計了varinish的架構
varnish術語解析html
緩存的衡量參數:命中率 # 1 文檔命中率 # 2 字節命中率 緩存類型: # 私有緩存 (好比客戶端的瀏覽器上的緩存) # 公共緩存 (好比一個組織機構創建的緩存服務器) 緩存的層次結構 #客戶端 <---...-->2級代理<--------->1級代理 <----------->原始服務器
內容路由 #ICP : Internet Cache Protocol 互聯網緩存協議 #CARP: Cache Array Routing Protocol 緩存陣列路由協議---用的比較多
緩存處理客戶端請求的具體步驟 #接受請求 #解析請求 (代理的功能) #查詢緩存 (檢查本地緩存中是否存在對方請求的內容的副本) #副本的新鮮度檢測 (檢查本地緩存的副本是否爲最新版本) #構建響應 (代理的功能---做爲某個應用程序的代理服務器) #發送 #日誌
保證副本的新鮮度? # 文檔過時機制:-----------響應首部 HTTP/1.0 : Expires (過時時間) 絕對時間 -----好比2014年5月5日過時 HTTP/1.1 :Cache-Control (max-age=) 相對時長 ------好比還有100小時可用 # 條件式請求: --------------請求首部 1 mtime: If-Modified-Since 基於時間的條件式請求 2 ETag :If-None-Match 基於拓展標籤條件式請求
原始服務器、緩存服務器、客戶端 如何實現對緩存的控制 (1) 原始服務器或緩存服務器控制緩存的能力 # 由原始服務器定義: Cache-Control Cacmax-age =(屬於私有緩存中) s-maxage =(屬於公共緩存中) no-store :不能緩存 no-cache :能緩存下來,但不能直接使用此緩存對象; 緩存對象在使用之間必須作 新鮮度驗證 must-revalidate:必須進行新鮮度驗證 private : 客戶端的私有數據,不緩存 public : 公共數據,緩存 #原始服務器不添加任何控制機制,而由緩存服務器本身決定緩存時長 (2)客戶端對緩存使用狀況的控制 # 客戶端控制是否使用緩存: Cache-Control: max-stale:告知緩存機制可使用過時的文件 no-cache :告知緩存機制必須進行驗證,不然不會接受任何緩存文檔; no-store :告知緩存機制必須儘快刪除緩存中的文檔
Varnish 基本架構node
如上圖所示: (1) varnish主要運行兩個進程: Management進程和Child進程(也叫Cache進程)。 # Management進程主要實現應用新的配置、編譯VCL、監控varnish、初始化varnish以及提供一個命令行接口等。Management進程會每隔幾秒鐘探測一下Child進程以判斷其是否正常運行,若是在指定的時長內未獲得Child進程的迴應,Management將會重啓此Child進程。 # Child進程包含多種類型的線程 # Accept線程:接收新的鏈接請求並響應; # Worker線程:child進程會爲每一個會話啓動一個worker線程,所以,在高併發的場景中可能會出現數百個worker線程甚至更多; # Expiry線程:從緩存中清理過時內容;
(2)varnish日誌 #爲了與系統的其它部分進行交互,Child進程使用了能夠經過文件系統接口進行訪問的共享內存日誌(shared memory log) #共享內存日誌大小通常爲80M,其分爲兩部分,前一部分爲計數器,後半部分爲客戶端請求的數據。varnish提供了多個不一樣的工具如varnishlog、varnishncsa或varnishstat等來分析共享內存日誌中的信息並可以以指定的方式進行顯示。
(3)VCL # Varnish Configuration Language (VCL)是varnish配置緩存策略的工具 # 使用VCL編寫的緩存策略一般保存至.vcl文件中,其須要編譯成二進制的格式後才能由varnish調用 # 整個緩存策略就是由幾個特定的子例程如vcl_recv、vcl_fetch等組成 VCL語法 # (1)//、#或/* comment */用於註釋 # (2)sub $name 定義函數 ---即定義子例程 # (3)不支持循環,有內置變量 # (4)使用終止語句,沒有返回值 # (5)域專用 # (6)操做符:=(賦值)、==(等值比較)、~(模式匹配)、!(取反)、&&(邏輯與)、||(邏輯或)
(4)varnish後端存儲 # 1)file:使用特定的文件存儲所有的緩存數據; # 2)malloc:使用malloc()庫調用在varnish啓動時向操做系統申請指定大小的內存空間以存儲緩存對象; # 3)persistent(experimental):與file的功能相同,但能夠持久存儲數據(即重啓varnish數據時不會被清除);仍處於測試期;
狀態引擎(子例程)linux
VCL中由多個子例程組成,各個子例程之間有必然的關係,以下圖所示web
如上圖 pipe 、lookup、pass 爲vcl_recv 子例程的返回狀態。依據此狀態來判斷下一步的去向正則表達式
VCL中的變量vim
Varnish的安裝配置後端
環境搭建瀏覽器
如上圖 varnish服務器 172.16.13.2 外網網卡 192.168.20.11 內網網卡 後端服務器兩個 192.168.20.12 服務器一內網地址 192.168.20.13 服務器二內網地址
準備工做緩存
1 配置以上三臺服務器的ip地址,此處不作詳解 2 server1服務器 編輯web頁面 #vim /var/www/html/index.html <h1>node12.linux.com</h1> #service httpd start 3 server2服務器 編輯web頁面 #vim /var/www/html/index.html <h1>node13.linux.com</h1> #service httpd start
安裝varnish並配置
1)下載3.0版本的varnish varnish-3.0.4-1.el6.x86_64.rpm varnish-libs-3.0.4-1.el6.x86_64.rpm varnish-docs-3.0.4-1.el6.x86_64.rpm 2)安裝 # rpm -ivh varnish*.rpm 安裝以上三個包 # rpm -ql varnish 3)編輯varnish配置文件,定義varnish啓動時的特性 #vim /etc/sysconfig/varnish NFILES=131072 打開的最大文件數 MEMLOCK=82000 默認分配給日誌log的內存數82M NPROCS="unlimited" 最大線程數 ,無限制 RELOAD_VCL=1 從新啓動服務時候,是否從新編譯vcl 從新使用vcl VARNISH_VCL_CONF=/etc/varnish/default.vcl vcl配置緩存策略的配置文件 VARNISH_LISTEN_PORT=80 varnish偵聽的默認端口爲6081,接受用戶請求 ----------通常更改成80端口 VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 varnish管理偵聽的地址 VARNISH_ADMIN_LISTEN_PORT=6082 varnish管理接口, VARNISH_SECRET_FILE=/etc/varnish/secret 進入varnish管理接口的密鑰文件 VARNISH_MIN_THREADS=50 最小線程數 VARNISH_MAX_THREADS=1000 最大線程數---------varnish超過5000個線程後會不穩定 VARNISH_THREAD_TIMEOUT=120 空閒線程轉向工做線程的延遲時間 VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin 基於文件存儲時的文件路徑 VARNISH_STORAGE_SIZE=1G 後端存儲的的大小 VARNISH_STORAGE="malloc,100M" 自定義內存大小 VARNISH_TTL=120 請求後端服務器的超時時間 4)啓動服務 # service varnish start # ss -ntlp | grep 80
5 ) 進入varnish管理界面 #varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> help --------查看一下全部的命令參數 200 help [command] ping [timestamp] auth response quit banner status start stop vcl.load <configname> <filename> 加載編譯某個vcl,加載的時候並指定一個配置名稱(該名稱隨意指定) vcl.inline <configname> <quoted_VCLstring> vcl.use <configname> vcl.discard <configname> vcl.list 列出全部的vcl vcl.show <configname> 查看已經列出的vcl param.show [-l] [<param>] param.set <param> <value> panic.show panic.clear storage.list
6 ) 建立vcl文件 #vim /etc/varnish/test.vcl 內容以下 backend websrv1 { .host = "192.168.20.12"; .port = "80"; } 進入管理界面編譯使用 #varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 varnish> vcl.load test2 test.vcl ------------------加載編譯test.vcl 200 VCL compiled. varnish> vcl.use test2 -----------------使用已經編譯好 test.vcl 200 varnish> vcl.show test2 ------------------查看test.vcl 的內容 200 backend websrv1 { .host = "192.168.20.12"; .port = "80"; }
7)客戶端測試
接下來進行vcl的功能拓展
1、 判斷上邊的配置是否命中緩存
(1)編輯test.vcl #vim /etc/varnish/test.vcl backend websrv1 { .host = "192.168.20.12"; .port = "80"; } sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT"; } else { set resp.http.X-Cache = "MISS"; } } (2)管理界面中從新編譯 並使用 # varnish > vcl.load test3 test.vcl # varnish > vcl.use test3 (3)在varnish服務器測試 # curl -I http://172.16.13.2
命中
2、判斷從哪一個服務器命中緩存 ---使用變量server.ip
編輯test.vcl #vim /etc/varnish/test.vcl backend websrv1 { .host = "192.168.20.12"; .port = "80"; } sub vcl_deliver { if (obj.hits > 0) { set resp.http.X-Cache = "HIT" + server.ip; } else { set resp.http.X-Cache = "MISS"; } } 管理界面 從新編譯並使用 # varnish > vcl.load test4 test.vcl # varnish > vcl.use test4 服務器測試 # curl -I http://172.16.13.2
3、 拒絕使用緩存 ---使用變量req.url
server2服務器再建立一個測試頁面 #vim /var/www/html/test.html <h1>test!!!</h1> 編輯vcl配置文件增長vcl_recv子例程 #vim /etc/varnish/test.vcl sub vcl_recv { if (req.url ~ "test.html") { return(pass); } return(lookup); } varnish服務器測試 # curl -I http://172.16.13.2/test.html
所有miss,未命中
4、定義緩存時長
若是客戶端請求的爲圖片文件,就緩存7200s, 若是客戶端請求的爲靜態網頁,就緩存1200s 編輯test.vcl 增長子例程vcl_fetch #vim /etc/varnish/test.vcl sub vcl_fetch { if (req.url ~ "\.(jpg|jpeg|gif|png)$") { set beresp.ttl = 7200s; } if (req.url ~ "\.(html|css|js)$") { set beresp.ttl = 1200; } } #serivice varnish reload 管理界面從新編輯 並使用 #varnish > vcl.load test6 test.vcl #varnish > vcl.use test6
五 使用PURGE修剪緩存
修剪緩存很是危險,因此咱們必需要作好準備 在具體執行某清理工做時,須要事先肯定以下問題: #(1)僅須要檢驗一個特定的緩存對象,仍是多個? #(2)目的是釋放內存空間,仍是僅替換緩存的內容? #(3)是否是須要很長時間才能完成內容替換? #(4)這類操做是個平常工做,仍是僅此一次的特殊需求? 移除單個緩存的實現 #vim /etc/varnish/test.vcl 增長內容以下 acl purgers { "127.0.0.1"; "172.16.0.0"/16; } sub vcl_recv { if (req.request == "PURGE") { if (!client.ip ~ purgers) { error 405 "Method not allowed"; } } if (req.url ~ "test.html") { return(pass); } return(lookup); } sub vcl_hit { if (req.request == "PURGE") { purge; error 200 "PURGE OK"; } } sub vcl_miss { if (req.request == "PURGE") { purge; error 404 "Not in cache"; } } sub vcl_pass { if (req.request == "PURGE") { error 502 "Purged on a passed object"; } } 管理界面從新編譯vcl並使用 #varnish > vcl.load test8 vcl.test #varnish > vcl.use test8 測試 客戶端在發起HTTP請求時,只須要爲所請求的URL使用PURGE方法便可 使用 curl -I -X PURGE http://varniship/path/to/someurl
6、定義varnish服務器檢測後端服務器健康狀態
後端服務器爲 192.168.12.12和 192.168.12.13 #vim /etc/varnish/test.vcl backend web1 { .host = "192.168.20.12"; .port = "80"; .probe = { .url = "/index.html"; .interval = 1s; .window = 5; .threshold = 2; } } backend web2 { .host = "192.168.20.13"; .port = "80"; .probe = { .url = "/index.html"; .interval = 1s; .window = 5; } .threshold = 2; } director webs random { { .backend = web1; .weight = 2; } { .backend = web2; .weight = 1; } } 同時在子例程 vcl_recv 中添加調用req.backend set req.backend = webs; 管理接口從新編譯vcl 並好似用 # varnish > vcl.load test9 vcl.test # varnish > vcl.use test9
客戶端測試
首先關閉192.168.20.12 服務器的httpd服務
啓動192.168.20.12 httpd服務
七 將請求的靜態網頁發送至web1服務器
將請求的圖片發送至web2服務器
編輯test.vcl # vim /etc/varnish/test.vcl 添加以下內容 sub vcl_recv { if (req.url ~ "\.(html|css|js)$") { set req.backend = web1; } else { set req.backend = web2; } #同時註釋掉director全部內容
八 如何防盜鏈
搜的例子: if (req.http.referer ~ "http://.*") { if ( !(req.http.referer ~ "http://.*ixdba\.net" || req.http.referer ~ "http://.*google\.com" || req.http.referer ~ "http://.*yahoo\.cn"et || req.http.referer ~ "http://.*google\.cn" )) { set req.http.host = "www.ixdba.net"; set req.url = "/templets/default/p_w_picpaths/logo.gif"; } return (lookup); }
varnish經常使用的工具
1 varnishstat 查看狀態的命令工具 用法: -1 -l:列出全部參數 -f f1,f2 例如 varnishstat -f cache_hit,cache_miss 只查看這兩項 # 須要關注的幾個參數 cache hit cache miss client_req client_conn n_wrk n_wrk_create n_backend n_expired n_lru_moved s_hdrbytes s_bodybytes 2 varnishtop 實時顯示日誌中的信息 用法: -i tag : 僅顯示指定的tag,如RxHeader -I regexp : 以模式匹配tag對應值; -C :正則表達式匹配時不區分字符大小寫; 3 varnishlog #server varnishlog start 開啓varnishlog #tail -f /var/log/varnish/varnish.log 4 varnishreplay 日誌重放工具,用於實現緩存預熱
幾個重要調整的參數
# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 # varnish> help # varnish> param.show 查看全部參數 幾個重要的參數 thread_pool_add_delay 兩個客戶端建立線程池時的時間間隔 thread_pool_fail_delay 建立線程池失敗後,第二次建立時的時間間隔 thread_pool_max 一個線程池中默認裝載的最大的線程數 thread_poo_min 一個線程池中默認裝載的最小的線程數,限定避免其過於不均衡,防止在繁忙中有的線程池不能少於這個值 thread_pool_purge_delay 多長時間清理一次線程, thread_pool_timeout 一個線程空閒多長時間 就清除掉 thread_pool_workspace 一個線程池 thread_pools 工做線程池的個數 thread_stats_rate 一批蒐集多少個工做線程的狀態信息 參數調整方法 # varnish> param.show thread_pools # varnish> param.set thread_pools 3 # varnish> param.show thread_pools
思考篇
緩存命中率低的緣由
緩存空間過小 --------------增大內存,增大磁盤 不存在明顯的熱點數據------------(二八法則:80%的請求落在20%的數據上 )---能夠不用作緩存了,或者將原數據所有作到緩存 源文件更新過於頻繁 -----------建議不要使用緩存了 緩存服務器的可用性 ---------------作分佈式