web_cache_server -- Varnish
生活随笔
收集整理的這篇文章主要介紹了
web_cache_server -- Varnish
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
web cache server : Varnish (web reserve proxy)
一 關于Varnish
1 Varnish的系統架構.
Varnish主要運行兩個進程,Management進程和Child進程:
Management進程主要實現初始化varnish,監控varnish,編譯VCL和提供了一個命令行接口,Management進程會每隔幾秒鐘就會探測一下Child進程以判斷其是否運行正常,如果在指定的時間內沒有得到Child進程的回應,Management進程會重啟Child進程.
Child進程包含多種類型的線程:?
Acceptor線程,接受新的連接請求并回應.
Worker線程,Child進程會為每一個請求分配一個worker線程處理.
Expire線程,從緩存中清理過期內容.
2 VCL Varnish ?Configure ?Language?
VCL(varnish configure language)是一門編程語言,它支持有限的算術運算和邏輯運算,允許使用正則表達式進行字符串匹配,允許用戶使用set設置變量的值,支持if判斷語句,也有內置的變量.
VCL可以同時保存幾份尚在引用的舊版本配置,也能夠讓新的配置立即生效,編譯后的舊版本配置通常在varnish重啟是才會別丟棄,如果需要手動清理也可以使用 varnishadm 的 vcl.discard命令完成.
3 Varnish 的后端存儲.
Varnish支持多種類型的后端存儲,這可以在varnish啟動的時候設定,后端處處的類型如下:
(1) file 使用特定的文件存儲全部的緩存數據,并通過操作系統的mmap()系統調用將整個文件映射到內存區域中. 在重啟varnish的時候 數據會丟失
(2) maiiloc 使用malloc()系統調用在varnish啟動的時候向操作系統申請置頂大小的內存空間以存儲緩存對象. 在重啟varnish的時候 數據會丟失
(3) persistent 類似file 但是在varnish重啟的時候數據b不會丟失,但是這個機制還不太穩定.
為Varnish的指定使用的緩存的類型:
malloc[,size]
file[,path[,size[,granularity]]]
二 VCL Varnish Configure Language?
1 VCL狀態引擎
varnish開始處理一個請求的時候,首先需要分析HTTP請求本身,比如從首部獲取請求方法,驗證其是否是一個合法的HTTP請求,當這些基本分析結束之后需要作出一個決定,就是是否需要從緩存中查找請求資源這個決定就是使用vcl_recv方法決定的,如果管理員沒有自定義vcl_recv函數,varnish仍將執行默認的vcl_recv函數,事實上varnish官方強烈建議執行默認的vcl>recv函數以便處理自定義vcl_recv函數中可能出現的故障.
2 VCL 語法 Varnish Configure Language
VCL的設計參考了C和Perl語言,其基本的語法如下:
(1) // # /* */ 注釋
(2) sub 定義子例程(函數)
(3) 不支持循環 有內置函數
(4) 沒有返回值 但是可以使用終止語句return?
(5) 操作符 =(賦值) ==(等值比較) ~(模式匹配) ! && ||
3 vcl_recv
vcl_recv 是在varnish完成對請求報文的解碼為基本數據結構后第一個要執行的子例程,它通常有以下四個主要功能:
(1) 修改客戶端的數據以減少換緩存對象差異
(2) 基于客戶端數據選用換緩存策略
(3) 為web應用程序執行URL重寫
(4) 挑選合適的后端web服務器
可以使用下面電費終止語句
pass 繞過緩存,就是不從緩存中查詢內容或不將內容存儲在緩存中.?
pipe 不對客戶端的進行驗證操作,而是客戶端與后端服務器之間建立專用的管道,并直接將數據在二者之間進行傳遞,此時
lookup 在緩存中查找用戶的請求.
error 有varnish自己合成一個響應報文,一般是響應一個錯誤類信息,
安全起見,一般在自己定義的vcl_recv中不要使用return() 終止語句,而是再執行默認額vcl_recv進行處理,并由其作出相應的處理策略:
4 vcl_fetch?
vcl_recv是根據客戶端的請求作出緩存決策的,vcl_fetch則是根據服務器的響應作出緩存決策的,在任何VCL狀態引擎中返回的pass都將有vl_fetch進行后續處理,通過return 能夠返回給varnish的操作指令:
(1) deliver 緩存該對象,并將其發往客戶端.
(2) hit_for_pass 不緩存次對象 但是可以導致后續對此對象的請求直接送達到vcl_pass進行處理
(3) restart 重啟vcl并增加重啟計數器
(4) error code [reason] 返回指定的錯誤代碼給客戶端并丟棄請求
可以使用自定義對對象的緩存時長 beresp.ttl?
三 修剪緩存對象:
1 緩存內容的修剪
提高緩存命中率的最有效途徑之一就是增加緩存對象的生存時間(TTL),但是這也可能帶來副作用,比如緩存的對象在到達為其指定的有效期之前已經失效,因此,手動檢驗緩存對象的有效性或很有可能成為服務器管理員的日常工作.
2 移除單個緩存對象.
purge用于清理緩存中的某特定的對象及變種
案例:
acl purges {
"127.0.0.1";
"172.31.0.0"/16;
}
sub vcl_recv {
if(req.request == "PURGE"){
if(!client.ip ~ "purges"){
error 405 “Method not Allowwd";
}
return(lookup);
}
}
sub vcl_hit {
if(req.request == "PRUGE"){
purge;
error 200 "Purge";
}
}
sub vcl_miss {
if(req.request == "PURGE"){
purge;
error 404 "Not IN Cache";
}
}
sub vcl_pass {
if(req.request == "PURGE"){
error 502 "PURGE Not";
}
}
變量的使用:
-----------------------------------------------------------------------------------------------------------------------------
? ? ? ??| vcl_recv | vcl_hash | vcl_hit | vcl_miss | vcl_fetch | vcl_deliver | vcl_pass | vcl_pipe |
-----------------------------------------------------------------------------------------------------------------------------
req.* | OK ? ? ? ? ? | OK ? ? ? ? ? ?| OK ? ? ? | OK ? ? ? ? ? | OK ? ? ? ? ? | OK ? ? ? ? ? ? ? | OK ? ? ? ? ? | OK ? ? ? ? ? |
-----------------------------------------------------------------------------------------------------------------------------
resp.* | ? ? ? ? ? ? ? ? | ? ? ?? ? ? ?| ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? | OK ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ?|
-----------------------------------------------------------------------------------------------------------------------------
breq.* | ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ?| OK ? ? ? ? ? | OK ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? | OK ? ? ? ? ? ?| ? ? ? ? ? ? ? ? |
-----------------------------------------------------------------------------------------------------------------------------
bresp.* | ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ?| OK ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? |?
-----------------------------------------------------------------------------------------------------------------------------
obj.hits ? | ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? | OK ? ? ? | ? ? ? ? ? ? ? | ? ? ? ? ?? ? ? ? | OK ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? |
-----------------------------------------------------------------------------------------------------------------------------
obj.* | ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? | OK ? ? ? | ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ?| ? ? ? ? ? ? ? |
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------
sub vcl_deliver {
if(obj.hits > 0){
set resp.http.X-Cache = "HIT";
}else{
set resp.http.X-Cache = "MISS";
}
}
-----------------------------------------
cookie :
sub vcl_recv {
if(!(req.url ~ "admin|login")){
unset req.http.cookie;
}
}
sub vcl_fetch {
if(!(req.url ~ "admin|login")){
unset beresp.http.set-cookie;
}
}
----------------------------------------------------------------------
案例:
backend web1 {
.host = "172.31.0.2";
.port = "80";
.probe = { //后端服務器的健康狀況檢測
.url = "/health.html";
.interval = 2s;
.window = 5;
.threshold = 2;
}
}
backend web2 {
.host = "172.31.0.3";
.port = "80";
.probe = {
.url = "/health.html";
.interval = 2s;
.window = 5;
.threshold = 2;
}
}
director webserver random { //后端服務器的負載均衡
{
.backend = web1;
.weight = 1;
}
{
.backend = web2;
.weight = 1;
}
}
acl purges {
"127.0.0.1";
"172.31.0.0"/16;
}
subb vcl_recv {
if(req.request == "PURGE"){
if(!client.ip ~ purges){
error 404 ”NOt ";
}
return(lookup);
}
if(req.url ~ "\.(js|html|css|png|jpeg|gif) && req.http.cookie){
unset req.http.cookie;
}
set req.backend = webserver;
if(req.url ~ "\.(js|css|html)$"){
set req.backend = web1
}
if(req.url ~ "\.(png|jpeg|gif)$"){
set req.backend = web2;
}
}
sub vcl_hit {
if(req.request == "PURGE"){
purge;
error 200 "OK";
}
}
sub vcl_miss {
if(req.request == "PURGE"){
purge;
error 500 "Not In Cache";
}
}
sub vcl_pass {
if(req.request == "PURGE"){
error 503 "NOt Allowed";
}
}
subb vcl_fetch {
if(req.url ~ "\.(js|css|html|png|jpeg|gif)$" && beresp.http.Set-Cookie){
unset beresp.http.Set-Cookie;
}
if(req.url ~ "\.(js|css|html)$"){
set beresp.ttl = 1200s;
set beresp.http.Expire = 1200;
}
if(req.url ~ "\.(png|jpeg|gif)$"){
set beresp.ttl = 7200s;
set beresp.http.Expire = 7200;
}
}
sub vcl_deliver {
if(obj.hits > 0){
set resp.http.X-Cache = "HIT";
}else{
set resp.http.X-Cacje = "MISS";
}
}
一 關于Varnish
1 Varnish的系統架構.
Varnish主要運行兩個進程,Management進程和Child進程:
Management進程主要實現初始化varnish,監控varnish,編譯VCL和提供了一個命令行接口,Management進程會每隔幾秒鐘就會探測一下Child進程以判斷其是否運行正常,如果在指定的時間內沒有得到Child進程的回應,Management進程會重啟Child進程.
Child進程包含多種類型的線程:?
Acceptor線程,接受新的連接請求并回應.
Worker線程,Child進程會為每一個請求分配一個worker線程處理.
Expire線程,從緩存中清理過期內容.
2 VCL Varnish ?Configure ?Language?
VCL(varnish configure language)是一門編程語言,它支持有限的算術運算和邏輯運算,允許使用正則表達式進行字符串匹配,允許用戶使用set設置變量的值,支持if判斷語句,也有內置的變量.
VCL可以同時保存幾份尚在引用的舊版本配置,也能夠讓新的配置立即生效,編譯后的舊版本配置通常在varnish重啟是才會別丟棄,如果需要手動清理也可以使用 varnishadm 的 vcl.discard命令完成.
3 Varnish 的后端存儲.
Varnish支持多種類型的后端存儲,這可以在varnish啟動的時候設定,后端處處的類型如下:
(1) file 使用特定的文件存儲全部的緩存數據,并通過操作系統的mmap()系統調用將整個文件映射到內存區域中. 在重啟varnish的時候 數據會丟失
(2) maiiloc 使用malloc()系統調用在varnish啟動的時候向操作系統申請置頂大小的內存空間以存儲緩存對象. 在重啟varnish的時候 數據會丟失
(3) persistent 類似file 但是在varnish重啟的時候數據b不會丟失,但是這個機制還不太穩定.
為Varnish的指定使用的緩存的類型:
malloc[,size]
file[,path[,size[,granularity]]]
二 VCL Varnish Configure Language?
1 VCL狀態引擎
varnish開始處理一個請求的時候,首先需要分析HTTP請求本身,比如從首部獲取請求方法,驗證其是否是一個合法的HTTP請求,當這些基本分析結束之后需要作出一個決定,就是是否需要從緩存中查找請求資源這個決定就是使用vcl_recv方法決定的,如果管理員沒有自定義vcl_recv函數,varnish仍將執行默認的vcl_recv函數,事實上varnish官方強烈建議執行默認的vcl>recv函數以便處理自定義vcl_recv函數中可能出現的故障.
2 VCL 語法 Varnish Configure Language
VCL的設計參考了C和Perl語言,其基本的語法如下:
(1) // # /* */ 注釋
(2) sub 定義子例程(函數)
(3) 不支持循環 有內置函數
(4) 沒有返回值 但是可以使用終止語句return?
(5) 操作符 =(賦值) ==(等值比較) ~(模式匹配) ! && ||
3 vcl_recv
vcl_recv 是在varnish完成對請求報文的解碼為基本數據結構后第一個要執行的子例程,它通常有以下四個主要功能:
(1) 修改客戶端的數據以減少換緩存對象差異
(2) 基于客戶端數據選用換緩存策略
(3) 為web應用程序執行URL重寫
(4) 挑選合適的后端web服務器
可以使用下面電費終止語句
pass 繞過緩存,就是不從緩存中查詢內容或不將內容存儲在緩存中.?
pipe 不對客戶端的進行驗證操作,而是客戶端與后端服務器之間建立專用的管道,并直接將數據在二者之間進行傳遞,此時
lookup 在緩存中查找用戶的請求.
error 有varnish自己合成一個響應報文,一般是響應一個錯誤類信息,
安全起見,一般在自己定義的vcl_recv中不要使用return() 終止語句,而是再執行默認額vcl_recv進行處理,并由其作出相應的處理策略:
4 vcl_fetch?
vcl_recv是根據客戶端的請求作出緩存決策的,vcl_fetch則是根據服務器的響應作出緩存決策的,在任何VCL狀態引擎中返回的pass都將有vl_fetch進行后續處理,通過return 能夠返回給varnish的操作指令:
(1) deliver 緩存該對象,并將其發往客戶端.
(2) hit_for_pass 不緩存次對象 但是可以導致后續對此對象的請求直接送達到vcl_pass進行處理
(3) restart 重啟vcl并增加重啟計數器
(4) error code [reason] 返回指定的錯誤代碼給客戶端并丟棄請求
可以使用自定義對對象的緩存時長 beresp.ttl?
三 修剪緩存對象:
1 緩存內容的修剪
提高緩存命中率的最有效途徑之一就是增加緩存對象的生存時間(TTL),但是這也可能帶來副作用,比如緩存的對象在到達為其指定的有效期之前已經失效,因此,手動檢驗緩存對象的有效性或很有可能成為服務器管理員的日常工作.
2 移除單個緩存對象.
purge用于清理緩存中的某特定的對象及變種
案例:
acl purges {
"127.0.0.1";
"172.31.0.0"/16;
}
sub vcl_recv {
if(req.request == "PURGE"){
if(!client.ip ~ "purges"){
error 405 “Method not Allowwd";
}
return(lookup);
}
}
sub vcl_hit {
if(req.request == "PRUGE"){
purge;
error 200 "Purge";
}
}
sub vcl_miss {
if(req.request == "PURGE"){
purge;
error 404 "Not IN Cache";
}
}
sub vcl_pass {
if(req.request == "PURGE"){
error 502 "PURGE Not";
}
}
變量的使用:
-----------------------------------------------------------------------------------------------------------------------------
? ? ? ??| vcl_recv | vcl_hash | vcl_hit | vcl_miss | vcl_fetch | vcl_deliver | vcl_pass | vcl_pipe |
-----------------------------------------------------------------------------------------------------------------------------
req.* | OK ? ? ? ? ? | OK ? ? ? ? ? ?| OK ? ? ? | OK ? ? ? ? ? | OK ? ? ? ? ? | OK ? ? ? ? ? ? ? | OK ? ? ? ? ? | OK ? ? ? ? ? |
-----------------------------------------------------------------------------------------------------------------------------
resp.* | ? ? ? ? ? ? ? ? | ? ? ?? ? ? ?| ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? | OK ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ?|
-----------------------------------------------------------------------------------------------------------------------------
breq.* | ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ?| OK ? ? ? ? ? | OK ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? | OK ? ? ? ? ? ?| ? ? ? ? ? ? ? ? |
-----------------------------------------------------------------------------------------------------------------------------
bresp.* | ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ?| OK ? ? ? ? ? | ? ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? |?
-----------------------------------------------------------------------------------------------------------------------------
obj.hits ? | ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? | OK ? ? ? | ? ? ? ? ? ? ? | ? ? ? ? ?? ? ? ? | OK ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? |
-----------------------------------------------------------------------------------------------------------------------------
obj.* | ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? | OK ? ? ? | ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ? ? ?| ? ? ? ? ? ? ? ? ? | ? ? ? ? ? ? ?| ? ? ? ? ? ? ? |
-----------------------------------------------------------------------------------------------------------------------------
-----------------------------------------
sub vcl_deliver {
if(obj.hits > 0){
set resp.http.X-Cache = "HIT";
}else{
set resp.http.X-Cache = "MISS";
}
}
-----------------------------------------
cookie :
sub vcl_recv {
if(!(req.url ~ "admin|login")){
unset req.http.cookie;
}
}
sub vcl_fetch {
if(!(req.url ~ "admin|login")){
unset beresp.http.set-cookie;
}
}
----------------------------------------------------------------------
案例:
backend web1 {
.host = "172.31.0.2";
.port = "80";
.probe = { //后端服務器的健康狀況檢測
.url = "/health.html";
.interval = 2s;
.window = 5;
.threshold = 2;
}
}
backend web2 {
.host = "172.31.0.3";
.port = "80";
.probe = {
.url = "/health.html";
.interval = 2s;
.window = 5;
.threshold = 2;
}
}
director webserver random { //后端服務器的負載均衡
{
.backend = web1;
.weight = 1;
}
{
.backend = web2;
.weight = 1;
}
}
acl purges {
"127.0.0.1";
"172.31.0.0"/16;
}
subb vcl_recv {
if(req.request == "PURGE"){
if(!client.ip ~ purges){
error 404 ”NOt ";
}
return(lookup);
}
if(req.url ~ "\.(js|html|css|png|jpeg|gif) && req.http.cookie){
unset req.http.cookie;
}
set req.backend = webserver;
if(req.url ~ "\.(js|css|html)$"){
set req.backend = web1
}
if(req.url ~ "\.(png|jpeg|gif)$"){
set req.backend = web2;
}
}
sub vcl_hit {
if(req.request == "PURGE"){
purge;
error 200 "OK";
}
}
sub vcl_miss {
if(req.request == "PURGE"){
purge;
error 500 "Not In Cache";
}
}
sub vcl_pass {
if(req.request == "PURGE"){
error 503 "NOt Allowed";
}
}
subb vcl_fetch {
if(req.url ~ "\.(js|css|html|png|jpeg|gif)$" && beresp.http.Set-Cookie){
unset beresp.http.Set-Cookie;
}
if(req.url ~ "\.(js|css|html)$"){
set beresp.ttl = 1200s;
set beresp.http.Expire = 1200;
}
if(req.url ~ "\.(png|jpeg|gif)$"){
set beresp.ttl = 7200s;
set beresp.http.Expire = 7200;
}
}
sub vcl_deliver {
if(obj.hits > 0){
set resp.http.X-Cache = "HIT";
}else{
set resp.http.X-Cacje = "MISS";
}
}
總結
以上是生活随笔為你收集整理的web_cache_server -- Varnish的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web_reverse_proxy --
- 下一篇: GVIM编辑器的配置