一 varnish 簡介
varnish 是一款高性能的開源的HTTP加速器,採用了“VisualPage Cache”技術,被安裝在web應用程序前面,緩存web應用程序,並響應用戶請求,varnish 讓您的web應用程序運行的更快,並且varnish 具有更加靈活,效率更高,資源佔用的更少等優點。
varinish 特點
1 是基於內存緩存,重啓數據將消失
2 利用虛擬內存方式,IO性能好
3 VCL 配置管理比較靈活
4 32 爲系統上緩存文件大小爲2G
5 具有更強大的管理功能,
6 具有強大的管理功能,例如varnishtop,varnishstat,varnishadmin等
7 利用二交叉堆管理緩存文件,達到積極刪除目的
varnish的storage 方式可分爲兩種:
1 malloc 通過malloc 獲取內存
2 mmap file 創建大文件,通過二分法分段映射成1G以內的大塊。
varnish 進程的工作模式:
varnish 啓動或者有2個進程master(managemment)進程和child(worker)進程。master 讀入存儲配置命令,進行初始化,然後fork,監控child。child則分配線程進行cache工作,child還會做管理線程和生成很多worker線程。
child 進程主線程初始化過程中,將存儲大文件整個加載到內存中,如果該文件中超出系統的虛擬內存,則會減少原來配置mmap 大小,然後繼續加載,這個時候創建並初始化空閒存儲結構體,放在存儲管理的struct中,等待分配
接着varnish某個負責接口新http連接開始等待用戶,如果有新的http連接,但是這個線程只負責接收,然後幻想等待線程池中的work線程,進行請求處理。
worker線程讀入uri後,將會查找已有的object,命中直接返回,沒有命中,則會從後端服務器中取出來,放到緩存中。如果緩存已滿,會更加LRU算法,釋放舊的object。對於釋放緩存,有一個超時線程會檢測緩存中所有的object的生命週期,如果緩存過期(ttl),則會刪除,是否相應的存儲內存。
varnish工作流程:
主進程fork 子進程,主進程等待子進程的信號,子進程退出後,主進程重新啓動子進程,子進程生成若干線程
Accept線程:接收請求後,組織成session結構,看是否空閒的工作線程,如果有,將請求給它,如果overflow 過大,則放棄該請求,否則,將其掛在overflow 上
Work線程:從overflow隊列上摘取請求(structses),進入狀態處理過程,處理結束後,通過pipe通信,將struct ses 發送給epoll線程
Epoll 線程:將一個請求處理稱作一個session,在session 週期內,處理完請求後,會交給epoll處理,若還沒有過期,將socket放入epoll的事件中,事件發生時,也會將其放入overflow中
Expire線程:對於緩存的對象,根據過期時間,組織成二交叉堆,該線程週期檢查該堆的根,處理過期的文件。
二 varnish 內置函數
1 vcl_recv 函數
用於接收和處理請求。當請求到達併成功接收後被調用,通過判斷請求的數據來決定如何處理請求。例如如何響應,怎麼響應,使用那個後端服務器等
此函數一般以如下幾個關鍵字結束。
pass: 表示進入pass模式,把請求控制權交給vcl_pass函數
pipe:表示進入pipe模式,把請求控制權交個vcl_pipe函數
lookup:表示進入lookup模式,把請求控制權交給lookup指令,在緩存中查找被請求的對象,並且根據查找的結果把控制權交給vcl_hit 或者函數vcl_miss。
error code [reason]: 表示返回“code”給客戶端,並放棄處理請求。“code”是錯誤標識,例如200 和405 等。“reason”是錯誤提示信息
2 vcl_pipe 函數
此函數在進入pipe 模式時被調用,用於將請求直接傳遞至後端主機,在請求和返回的內容沒有改變的情況下,將不變的內容返回給客戶端,知道這個連接被關閉。
此函數一般以如下幾個關鍵字結束
error code [reason]
pass
restart 重新啓動流程,增加啓動次數,如果重新啓動次數高於max_restart 發出一個錯誤警告
3 vcl_hash
當您想把一個數據添加到hash 上時,調用此函數
4 vcl_hit
在執行lookup 指令後,在緩存中找到請求的內容後將自動調用該函數。
此函數一般以如下幾個關鍵字結束。
deliver:表示將找到的內容發送個客戶端,並把控制權交給函數vcl_deliver。
error code [reason]
pass
restart 重啓啓動流程,增加啓動次數,如果重新啓動次數高於max_restart 發出一個錯誤警告
5 vcl_miss 函數
在執行lookup 指令後,在緩存中沒喲找到請求的內容時自動調用該方法。此函數可用於判斷是否需要衝後端服務器獲取內容,此函數一般以如下幾個關鍵字結束
fetch:表示從後端獲取請求的內容,並把控制權交給vcl_fetch函數
error code [reason]
pass
6 vcl_fetch函數
在後端主機更新緩存並且獲取內容後調用該方法,接着,通過判斷獲取的內容來決定是將內容放入緩存,還是直接返回給客戶端。
如此函數一般以如下幾個關鍵字結束
error code [reason]
pass
deliver
esi
restart 重新啓動流程,增加啓動次數,如果重新啓動次數高於max_restart ,發出一個錯誤警告
7 vcl_deliver 函數
將在緩存中找到請求的內容發送給客戶端前調用此方法
此函數一般以如下幾個關鍵字結束
error code [reason]
deliver
restart 重新啓動流程,增加啓動次數,如果重新啓動次數高於max_restarts 發出一個錯誤警告
8 vcl_error
出現錯誤時調用此函數。
此函數一般以如下幾個關鍵字結束
deliver。
restart
在vcl 中有個三個重要的數據結構:request,response,object
request: 數據從客戶端進來,對應req對象,當varnish 收到一個請求的時候就會創建req對象,在vcl_recv中的大部分工作都是在req對象展開的
response:數據從後端服務器過來,對應beresp 對象,它包含從後端服務器傳遞過來數據的頭信息,在vcl_fetch 中的大部分工作都是在beresp 對象展開的。
object:存儲在cache 中的數據,對於obj對象,大多數只讀的對象存貯在內粗中,只有obj.ttl是可寫的,其餘都是隻讀的
vcl 支持下列運算符
= 賦值
== 比較
~ 匹配
! 否定
&&邏輯與
|| 邏輯或
三 varnish 請求處理流程
詳細的處理過程
四 varnish 內置公用變量
1 VCL 內置的公用變量可以用在不同的VCL 函數中,根據這些公用變量使用不同階段,下面依次介紹當請求到達後,可以使用的公用變量如下所示
req.backend 指定對應的後端主機
server.ip 表示服務器端IP
client.ip 表示客戶端IP
req.request 指定請求類型,例如GET,HEAD,POST等
req.url 指定請求的地址
req.proto 表示客戶端發起請求的HTTP協議版本
req.http.header 表示請求中http頭部信息
req.restarts 表示請求重啓的次數,默認最大值爲4
req.grace 表示,當一個請求命中了一個剛剛過期的object,由於回源需要一段時間,爲了立刻返回,那麼在過期後的req.grace時間內,可以將過期的那個object返回給客戶端,當然,這要求beresp.grace >= req.grace
2 varnish在向後端主機請求時,可以使用的公用變量如下所示:
beresp.request 指定請求的類型,例如GET,HEAD等
beresp.url 指定請求的地址
beresp.proto 表示客戶端發起請求的http 協議版本
beresp.http.header 表示對應請求中http 頭部信息
beresp.ttl 表示緩存的生存週期,也就是cache保留多長時間,單位是秒
beresp.grace 表示一個object即使已經過期了,仍然在緩存中存放一段時間
beresp.saintmode 設置saint模式,Saint mode允許您拋棄一個後端服務器或者另一個嘗試的後端服務器或者cache中服務陳舊的內容
beresp.do_gzip 在存儲object之前gzip對象,默認是false
3 從cache 或者後端主機獲取內容後,可以使用的公用變量如下所示
obj.status 表示返回內容的請求狀態代碼,例如200,302,504等
obj.cacheable 表示返回的內容是否可以緩存,也就是說,如果HTTP返回時200.203,300,301,302,404,410等,並且有非0的生存期,則可以緩存
obj.valid 表示是否是有效的HTTP應答
obj.reqponse 表示返回內容的請求狀態信息
obj.proto 表示返回內容的HTTP協議版本
obj.ttl 表示返回內容的生存週期,也就是緩存時間,單位是秒
obj.lastuse 表示返回上一次請求到現在的時間間隔,單位是妙
4 對客戶端應答時,可以使用的公用變量如下所示
resp.status 表示返回給客戶端的HTTP狀態代碼
resp.proto 表示返回給客戶端的HTTP協議版本
resp.http.header 表示返回給客戶端的HTTP協議版本
resp.response 表示返回給客戶端的HTTP 狀態信息
req.backend.healthy 後端是否健康存活,需要設置probe
五 varnish 管理工具詳解
1 varnishd 指令
-a address:port 表示varnish對httpd 的監聽地址及端口
-b address:port 表示後端服務器地址及端口
-d 表示使用debug 調試模式
-f file 指定varnish服務器的配置文件
-p param=value 指定服務器的參數,用來優化varnish性能
-P file varnish進程PID文件存放路徑
-n dir 指定varnish的工作目錄
-s kind[,storageoptions]指定varnish緩存內容的存放方式,常用的方式有:“-s file,<dir_or_file>,<size>”
其中”<dir_or_file>”指定緩存文件的存放路徑,“<size>” 指定緩存文件的大小
-t 指定缺省的TTL 值
-T address:port 設定varnish的telnet 管理端口地址及其端口
-w int[,int[,int]] 設定varnish的工作線程數,常用的方式有:
-w min,max
-w min,max,timeout
-V 顯示版本號
-u 指定運行的用戶
2 varnsihncsa 以NCSA 的格式顯示日誌
varnishncsa 工具讀取共享內存的日誌,然後以apache/NCSA的格式顯示出來,下面的選項可以用
-a 當把日誌寫到文件裏時,使用附加,而不是覆蓋
-b 只顯示varnishd和後端服務器的日誌
-C 匹配正則表達式的時候,忽略大小寫差異
-c 只顯示varnishd和客戶端的日誌
-D 以進程方式運行
-d 在啓動過程中處理舊的日誌,一般情況下,varnishhist只會在進程寫日誌後啓動
-f 在日誌輸出中使用X-Forwarded-ForHTTP 頭代替client.ip
-l regex 匹配正則表達式的日誌,如果沒有使用-i或者-I,那麼所有的日誌都會匹配
-I tag 匹配指定的tag,如果沒有使用-I 或者-I,那麼所有的日誌都會被匹配
-n 指定varnish實例的名字,用來獲取日誌,如果沒有指定,默認使用主機名
-P file 記錄PID號的文件
-r file 從一個文件讀取日誌,而不是從共享內存讀取
-w file 把日誌寫到一個文件裏面代替現實他們,如果不是使用-a參數就會發生覆蓋,如果varnishlog在寫日誌時,接收到一個SIGHUP信號,他會創建一個新的文件,老的文件可以移走
-X regex 排除匹配正則表達式的日誌
-x tag 排除匹配tag的日誌
3 varnishlog 工具讀取和顯示共享內存的日誌
-a 當把日誌寫到文件裏時,使用附加,而不是覆蓋。
-b 只顯示varnishd和後端服務器的日誌
-C 匹配正則表達式的時候,忽略大小寫差異
-c 只顯示varnishd和客戶端的日誌
-D 以進程的方式運行
-d 在啓動過程中除了舊的日誌,一般情況下,varnishhist只會在進程寫入日誌後啓動
-I regex 匹配正則表達式的日誌,如果沒有使用-i或者-I,那麼所有的日誌都會匹配。
-I tag 匹配指定的tag,如果沒有使用-i或者-I,那麼所有的日誌都會被匹配。
-k num 只顯示開始的num個日誌記錄
-n 指定varnish實例的名字,用來獲取日誌,如果沒有指定,默認使用主機名
-O 以請求ID 給日誌分組,這個功能沒有多大用處。如果要寫到一個文件裏面使用-w 選項
-P file記錄PID號的文件
-r file 從一個文件讀取日誌,而不是從共享內存讀取
-s sum跳過開始的num條日誌
-u 無緩衝的輸出
-V 顯示版本,然後退出
-w file 把日誌寫到一個文件裏代替顯示他們,如果不是用-a參數就會發生覆蓋,如果varnishlog在寫日誌時,接收到一個SIGHUP信號,他會創建一個新的文件。老的文件可以移走。
-X regex 排除匹配正則表達式的日誌
-x tag 排除匹配tag 的日誌
如果-o 選項被指定,需要使用正則表達式和tag來制定需要的日誌
4 varnishreplay
varnishreplay 工具類似varnish logs 嘗試將流量複製。下面的參數是可用的:
-a backend 發送到這臺服務器的TCP 流量,指定一個地址和端口,這個選項只能被IPV4上支持
-D 打開debug模式
-r file 使用文件裏的語法分析日誌,這個參數是強制的
5 varnishsizes
varnishsizes 工具讀取varnishd(1)的共享內存日誌,生成一個連續不斷更新的柱狀圖顯示最後N 個請求的分佈。N 的值取決於左上角垂直刻度的高度。水平尺度私對數。如果命中,則是使用”|”表示,如果沒有命中,使用“#”表示
可使用的參數
-b 分析指定後端服務器的日誌,如果沒有使用-b和-c參數,varnish就充當他們
-C 忽略正則表達式的大小寫
-c 分析指定客戶端的日誌
-d 在啓動過程中處理舊的日誌,一般情況下,varnishhist只會在進程寫入日誌後啓動
-I regex 匹配正則表達式的日誌,如果沒有使用-I或者-I,那麼所有的日子都會匹配
-I tag 匹配指定tag,如果沒有使用-i或者-I,那麼所有的日誌都會被匹配。
-n 指定varnish實例的名字,用來獲取日誌,如果沒有指定,默認使用主機名
-r file 讀入日誌文件,代替共享內存。
-V 顯示版本號,然後退出。
-w delay 等待更新的延遲時間,默認是1秒
-X regex 排除匹配表達式的日誌
-x tag 排斥匹配tag 的日誌
6 varnishstat 工具顯示一個運行varnishd實例的相關統計數據。
可用的參數
-1 只顯示一次就退出
-f 使用逗號分隔字段列表來顯示,使用“^”開始排除列表
-l 監聽有效的列使用-f 參數
-n 指定varnishd實例來對去日誌,如果沒有指定,則默認使用主機名
-V 顯示版本號,然後退出
-W dealy 刷新時間間隔,默認1s
中心顯示中每列的含義,從左到右:
1 值
2 從最後一秒更新以來的每秒的一個平均值,或者一個不能計算的週期
3 從進程開始到現在每秒的平均值,或者是一個不能計算的週期
4 描述
當使用-1選項,輸入列的含義,從左到右:
1 特徵名字
2 值
3 從進程開始到現在沒秒的平均值,或者是一個不能計算的週期。
4 描述
7 varnishtop 工具讀取varnishd(1) 共享內存的日誌,連續不斷的更新和顯示日誌記錄。使用-I,-i,-X和-x 選項適當的過濾,它可以顯示一個排序關於請求的內容,客戶端,用戶代理,或者其他記錄在日誌的信息。
可選用的參數
-1 代替連續不斷的更新和顯示,只顯示一次然後退出。。暗示:-d
-b 包含指定後端服務器的日誌,如果沒有使用-b或-c,那麼varnishtop但當這兩種角色。
-C 使用正則表達式的時候忽略大小寫
-c 包含指定客戶端的日誌,如果沒有使用-b或-c,varnishtop但當這兩種角色
-d 啓動的時候是使用舊的日誌記錄,一般那情況下,varnishtop只讀取其他啓動以後生產的日誌。
-f 只顯示日誌的第一列
-I regex 匹配正則表達式的日誌,如果沒有使用-I 或者-i,那麼所有的日誌都會匹配。
-I tag 匹配指定的tag,如果沒有使用-i或者-I,那麼所有的日誌都會被匹配。
-n 指定varnish實例的名字,用來獲取日誌,如果沒有指定,默認使用主機名
-r file 讀入日誌文件,代替共享內存
-V 顯示版本號,然後退出
-X regex 排除匹配表達式的日誌
-x tag 排除匹配tag 的日誌
參考http://www.cnblogs.com/derekchen/archive/2011/12/09/2282909.html