Varnish緩存機制詳細介紹及簡單配置


Varnish是一款高性能的開源HTTP加速器,其主要用來作爲反向代理中的緩存服務器使用,但其實Varnish自己也是具備反向代理功能的,但在建立鏈接和維持鏈接上,與Nginx相比差距很大,如今有一個很流行的架構就是前端用Nginx做爲反向代理,後面加Varnish緩存服務器爲Web服務加速php


在將Varnish前先談談咱們的瀏覽器緩存機制,如今的瀏覽器基本都具備緩存功能,它能將咱們之前訪問過的靜態內容和可進行緩存的動態內容緩存再本地,然後在下次訪問相同資源時,若是能夠確認Server端的資源未發生修改,則能夠直接使用本地緩存的數據,而再也不須要再從server端加載數據html


可是須要注意的是有的資源就不能緩存,如不能靜態化的動態資源,及一些私人數據,如帳號密碼登陸時產生的cookie等前端


而緩存空間又分爲私有緩存空間和公有緩存空間,私有緩存空間主要緩存那些涉及到用戶私密的數據,如用戶常常瀏覽的網頁cookie,就不能隨意讓他人獲取(負責會暴露你的嗜好);而公有緩存通常對大多數人均可以一塊兒使用如Nginx,Varnish,Squid等能夠緩存不涉及隱私的數據node


通常緩存都具備有效期限,一旦過時,緩存就會失效,對於緩存資源是否失效由如下幾種判斷策略:nginx

1:Expire 在http響應的首部明確告訴client這個數據在社麼時候過時:如web

  Expire: 2016-12-29 10.54.59 則一旦到達這個時間緩存就會失效,但這種絕對時間有個缺陷就是,正則表達式

client和server上的時間可能不一樣步,甚至可能不在一個時區,這種方法主要在http1.0中才用shell


2:max-age:相對時間計時,在http響應的首部直接告訴client這個數據能夠緩存多久,則在這段時間以前緩存均可以直接使用express



3:Cahe-Control:用於定義全部緩存機制都必須遵循的緩存指示,這些指示有如下指令編程

public 說明這個資源能夠放在公共緩存上,不涉及隱私內容,全部人均可以使用

private 說明這個資源部能夠放在公共緩存上如Nginx,Varnish,Squid等

no-cache 說明此資源能夠緩存,但你不能直接使用,而是每次使用時都要向server端進行驗證,此資源是否發生了修改,若是沒有修改則可使用,若是修改了則從新從server端加載資源(no-cache通常用在資源隨時都有可能發生變化的場景)

no-store:能夠緩存但不能進行存儲

must-revalidate;與no-cache相似,能夠緩存,但使用前要驗證是否修改

注:Cache-Control中的設定時間會覆蓋Expire中定義的時間


可是有的網站的頁面可能有動態腳本生成因此它的頁面內容可能會在一秒內發生好幾回改變,因此時間戳計時法就有點粗糙,可能形成已近失效的資源仍然被使用

4:E-tag:響應報文的首部,用於在響應的web資源中定義版本標示,E-tag會爲每次改變的頁面生成一個隨機的標籤(網頁該變頻率低於秒也無影響),而下次client請求相同的資源時只須要對比一下E-tag,若是相同則資源未修改,直接使用本地緩存,不然從新加載


在http1.1中還引入了條件判斷機制 如:

If-modify-since:用在請求報文的首部,client訪問同一個資源時,會詢問server端,自從我上次獲取資源到如今,此資源是否發生了修改,若是修改了,server會發送修改後的資源給client,不然會返回304(not modify)狀態碼,直接使用本地緩存


If-none-match: 條件式判斷請求報文首部,client請求相同資源時,會詢問server,E-tag是否不匹配,若是回答yes,則內容發生了修改,no則未修改直接使用本地緩存


Vary:響應首部,原始server會根據不一樣的請求來源,發送不一樣的響應報文首部,最經常使用的vary如:accept-encording(client是否支持壓縮),若是client請求時報文首部說支持,則會壓縮響應client,不然以源碼響應


Age:緩存的server可發送一個額外的響應首部,用於指定響應的有效期限,瀏覽器一般根據此首部決定緩存的有效時長,若是響應報文首部還有max-age,那麼緩存有效時長爲max-age 減 Age



以下是一個資源請求和響應的報文的首部

Request URL:https://eclick.baidu.com/fp.htm?br=2&fp=7319E

Request Method:GET

Status Code:200 OK #若是有緩存server且緩存未修改則返回304(no modify)

Remote Address:123.125.115.164:443

Response Headers

view source

Accept-Ranges:bytes

Cache-Control:max-age=0

Connection:keep-alive

Content-Length:114

Content-Type:text/html

Date:Thu, 29 Dec 2016 03:29:56 GMT

ETag:"58638da3-72"

Expires:Thu, 29 Dec 2016 03:29:56 GMT

Last-Modified:Wed, 28 Dec 2016 10:02:11 GMT

Server:nginx

Request Headers

view source

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,p_w_picpath/webp,*/*;q=0.8

Accept-Encoding:gzip, deflate, sdch, br

Accept-Language:zh-CN,zh;q=0.8

Connection:keep-alive

Cookie:BDUSS=nJaZDdIVy1HYn5MRnpUTzdFRnhRQkN5TnF5eWF1UUZ0WXpHdTB0b1NGSllhZlpYQVFBQUFBJCQAAAA AAAAAAAEAAAB~NOBPvNnD5mk5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFjczldY3M5XQ

Host:eclick.baidu.com

Referer:https://pos.baidu.com/wh/o.htm?ltr=

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)            Chrome/51.0.2704.106 Safari/537.36

Query String Parameters

view source

view URL encoded



一個擁有優秀緩存策略的緩存服務器,能夠大大提升緩存的命中率,從而減輕後端原始服務器的壓力,也能夠爲用戶帶來更優秀的用戶體驗


在實際部署中,能夠將緩存server結合CDN(內容分發網絡)來使用,在智能DNS的幫助下,始終將用戶的請求分發到距離用戶最近的一臺緩存服務器上,若是沒有在當前緩存server上找到緩存資源,當前的緩存server會請求其上一級(通常也是緩存服務器,與當前緩存server爲父子關係),若是尚未就找原始服務器,從而能夠極大的下降高併發下帶給原始服務器的壓力,同時能夠加速用戶請求的響應時間,爲用戶帶來更加優秀的體驗,


CDN和緩存服務器的使用主要目的是加速響應,和減輕原始服務器壓力,讓請求儘可能少找原始server,但有些動態資源就必須經過原始服務器獲取(許多動態資源沒法進行靜態化),即時是靜態資源你也不可能所有進行整站緩存


其中CDN網絡通常都是按流量進行收費的,通常的大公司可能會選擇自建CDN網絡,而只能DNS有免費的,如DNSPod,也有收費的(性能好)



Varnish做爲緩存服務器與Squid相比


Varnish與Squid都是一個反向代理服務器,均可用做高性能的代理緩存服務器,而且都是開源軟件


Varnish穩定性很高,二者在完成相同負荷的工做時,Squid服務器發生故障的概率要高於Varnish,由於Squid須要常常重啓


Varnish訪問速度更快,Varnish採用了「Visual PageCache」技術,全部緩存數據都直接從內存讀取,而Squid是從硬盤讀取緩存數據,所以Varnish在訪問速度方面會更快


Varnish支持更多的併發鏈接,由於Varnish的TCP鏈接釋放要比Squid快,因此在高併發鏈接狀況下能夠支持更多的TCP鏈接


Varnish能夠經過管理端口,使用正則表達式批量清除部分緩存,而Squid作不到


Varnish進程一旦掛起、崩潰或者重啓,緩存數據都會從內存中徹底釋放,此時全部請求都會被髮送到後端服務器,在高併發狀況下,這會給後端服務器形成很大壓力


Varnish配置相比Squid簡單,監控接口豐富,性能好,但Squid資料多,功能豐富,支持對ACL的訪問控制


Varnish主要運行兩個進程:Management進程和Child進程(也叫Cache進程)。

 

Management進程主要實現應用新的配置、編譯VCL、監控varnish、初始化varnish以及提供一個命令行接口等。此外Management進程會每隔幾秒鐘探測一下Child進程以判斷其是否正常運行,若是在指定的時長內未獲得Child進程的迴應,Management將會重啓此Child進程。

 

Child進程包含多種類型的線程,常見的如:

Acceptor線程:接收新的鏈接請求並響應;

Worker線程:child進程會爲每一個會話啓動一個worker線程,所以,在高併發的場景中可能會出現數百個worker線程甚至更多;

Expiry線程:從緩存中清理過時內容;

 

Varnish依賴「工做區(workspace)」以下降線程在申請或修改內存時出現競爭的可能性。在varnish內部有多種不一樣的工做區,其中最關鍵的當屬用於管理會話數據的session工做區。

 

以下圖:


wKioL1hkdiGCamFtAACktDr-4Y0677.png


Varnish將數據緩存在內存中,而且將日誌也保存在內存中(不是在磁盤上,這樣就避免了I/O的產生),Varnish已啓動,就會預先分配必定的內存爲記錄日誌使用(包括記錄有多少client請求進來了,有多少client請求命中了,有多少沒命中等都會進行記錄)

Child進程使用了能夠經過文件系統接口進行訪問的共享內存日誌(shared memory log),所以,若是某線程須要記錄信息,其僅須要持有一個鎖,然後向共享內存中的某內存區域寫入數據,再釋放持有的鎖便可。而爲了減小競爭,每一個worker線程都使用了日誌數據緩存。

 

共享內存日誌大小通常爲90M,其分爲兩部分,前一部分爲計數器,後半部分爲客戶端請求的數據。varnish提供了多個不一樣的工具如varnishlog、varnishncsa或varnishstat等來分析共享內存日誌中的信息並可以以指定的方式進行顯示。




VCL(varnish Configuration Language)varnish的配置語言

Varnish的配置是給你一個接口,讓你用VCL這種語言去編一個程序(指明那些數據緩存,那些不緩存等等);VCL策略在啓用前,會由management進程將其轉換爲C代碼,再由gcc再次編譯成爲二進制格式才能執行^_^,因此Cache/Child進程的工做是由編譯完的share object(共享對象)決定的。


Varnish修改配置的開銷很是小,其能夠同時保有幾份尚在引用的舊版本配置,也可以讓新的配置即刻生效。編譯後的舊版本配置一般在varnish重啓時纔會被丟棄,若是須要手動清理,則可使用varnishadm的vcl.discard命令完成。


通常來講Varnish的併發能力超過5000性能就會出現降低,因此不能讓其支持太多的併發鏈接,若是併發很高,能夠再Varnish前段加調度器或反向代理服務器進行多臺Varnish的負載均衡



Varnish的後端存儲


varnish支持多種不一樣類型的後端存儲,這能夠在varnishd啓動時使用-s選項指定。後端存儲的類型包括:

(1)file:使用特定的文件存儲所有的緩存數據,並經過操做系統的mmap()系統調用將整個緩存文件映射至內存區域(若是條件容許);

(2)malloc:使用malloc()庫調用在varnish啓動時向操做系統申請指定大小的內存空間以存儲緩存對象;

(3)persistent(experimental):與file的功能相同,但能夠持久存儲數據(即重啓varnish數據時不會被清除);仍處於測試期;


varnish沒法追蹤某緩存對象是否存入了緩存文件,從而也就無從得知磁盤上的緩存文件是否可用,所以,file存儲方法在varnish中止或重啓時會清除數據。而persistent方法的出現對此有了一個彌補,但persistent仍處於測試階段,例如目前尚沒法有效處理要緩存對象整體大小超出緩存空間的狀況,因此,其僅適用於有着巨大緩存空間的場景。


選擇使用合適的存儲方式有助於提高系統性,從經驗的角度來看,建議在內存空間足以存儲全部的緩存對象時使用malloc的方法,反之,file存儲將有着更好的性能的表現。然而,須要注意的是,varnishd實際上使用的空間比使用-s選項指定的緩存空間更大,通常說來,其須要爲每一個緩存對象多使用差很少1K左右的存儲空間,這意味着,對於100萬個緩存對象的場景來講,其使用的緩存空間將超出指定大小1G左右。另外,爲了保存數據結構等,varnish自身也會佔去不小的內存空間。


爲varnishd指定使用的緩存類型時,-s選項可接受的參數格式以下:

malloc[,size] 或

file[,path[,size[,granularity]]] 或

persistent,path,size {experimental}

file中的granularity用於設定緩存空間分配單位,默認單位是字節,全部其它的大小都會被圓整。




A.Varnish狀態引擎(state engine)


VCL用於讓管理員定義緩存策略,而定義好的策略將由varnish的management進程分析、轉換成C代碼、編譯成二進制程序並鏈接至child進程(即實例)。varnish內部有幾個所謂的狀態(state),在這些狀態上能夠附加經過VCL定義的策略以完成相應的緩存處理機制,所以VCL也常常被稱做「域專用」語言或狀態引擎,「域專用」指的是有些數據僅出現於特定的狀態中。

一、VCL狀態引擎


在VCL狀態引擎中,狀態之間具備相關性,但彼此間互相隔離,每一個引擎使用return(x)來退出當前狀態並指示varnish進入下一個狀態。


Varnish開始處理一個請求時,首先須要分析HTTP請求自己,好比從首部獲取請求方法、驗正其是否爲一個合法的HTT請求等。當這些基本分析結束後就須要作出第一個決策,即varnish是否從緩存中查找請求的資源。這個決定的實現則須要由VCL來完成,簡單來講,要由vcl_recv方法來完成。若是管理員沒有自定義vcl_recv函數,varnish將會執行默認的vcl_recv函數。然而,即使管理員自定義了vcl_recv,但若是沒有爲自定義的vcl_recv函數指定其終止操做(terminating),其仍將執行默認的vcl_recv函數。事實上,varnish官方強烈建議讓varnish執行默認的vcl_recv以便處理自定義vcl_recv函數中的可能出現的漏洞。


二、VCL語法

VCL的設計參考了C和Perl語言,所以,對有着C或Perl編程經驗者來講,其很是易於理解。其基本語法說明以下:

(1)//、#或/* comment */用於註釋

(2)sub $name 定義函數

(3)不支持循環,有內置變量

(4)使用終止語句,沒有返回值

(5)域專用

(6)操做符:=(賦值)、==(等值比較)、~(模式匹配)、!(取反)、&&(邏輯與)、||(邏輯或)

VCL的函數不接受參數而且沒有返回值,所以,其並不是真正意義上的函數,這也限定了VCL內部的數據傳遞只能隱藏在HTTP首部內部進行。VCL的return語句用於將控制權從VCL狀態引擎返回給Varnish,而非默認函數,這就是爲何VCL只有終止語句而沒有返回值的緣由。同時,對於每一個「域」來講,能夠定義一個或多個終止語句,以告訴Varnish下一步採起何種操做,如查詢緩存或不查詢緩存等。


三、VCL的內置函數


VCL提供了幾個函數來實現字符串的修改,添加bans,重啓VCL狀態引擎以及將控制權轉回Varnish等。


regsub(str,regex,sub)

regsuball(str,regex,sub):這兩個用於基於正則表達式搜索指定的字符串並將其替換爲指定的字符串;但regsuball()能夠將str中可以被regex匹配到的字符串通通替換爲sub,regsub()只替換一次;

ban(expression):

ban_url(regex):Bans全部其URL可以由regex匹配的緩存對象;

purge:從緩存中挑選出某對象以及其相關變種一併刪除,這能夠經過HTTP協議的PURGE方法完成;

hash_data(str):

return():當某VCL域運行結束時將控制權返回給Varnish,並指示Varnish如何進行後續的動做;其能夠返回的指令包括:lookup、pass、pipe、hit_for_pass、fetch、deliver和hash等;但某特定域可能僅能返回某些特定的指令,而非前面列出的所有指令;

return(restart):從新運行整個VCL,即從新從vcl_recv開始進行處理;每一次重啓都會增長req.restarts變量中的值,而max_restarts參數則用於限定最大重啓次數。



如圖爲Varnish工做的流程圖

wKiom1hkdjayAt4nAAEcumFViZ4965.png



先由vcl_recv接受請求,若是vcl_recv上的函數return()值爲pass,則直接到vcl_pass引擎處理,再判斷要不要轉向後端server,再由vcl_fetch判斷是否須要進行緩存,不管需不須要都要最後交給vcl_deliver引擎處理


若是vcl_recv引擎return()的值爲lookup,則交給vcl_hash引擎處理,再判斷緩存中是否有須要的對象,若是有交給vcl_hit引擎,在交給vcl_pass引擎再判斷是否轉向後端server交給vcl_fetch,或者直接到vcl_deliver;若是沒有交給vcl_miss,則交給vcl_pass處理或者判斷完是否向後端轉發後,交給vcl_fetch引擎處理,vcl_fetch判斷是否須要緩存,不管緩存與否都要交給vcl_deliver處理;


其中的vcl_pass甚至能夠從新將請求轉到vcl_recv讓從新判斷,說不定第二次判斷就命中了,取決於你的策略


若是vcl_recvreturn()返回值爲pipe則直接交給vcl_pipe引擎,知道pipe utile close(管道關閉)



VCL內置函數應用以下所示:

[1]vcl_recv:用於接收和處理請求。當請求到達並被成功接收調用,經過判斷請求的數據來決定若是處理請求。例如:應該如何響應、經過什麼方式響應、調度使用哪一個後端服務器。

做用應用以下:

vcl_recv是在Varnish完成對請求報文的解碼爲基本數據結構後第一個要執行的子例程,它一般有四個主要用途:


(1)修改客戶端數據以減小緩存對象差別性;好比刪除URL中的www.等字符;

(2)基於客戶端數據選用緩存策略;好比僅緩存特定的URL請求、不緩存POST請求等;

(3)爲某web應用程序執行URL重寫規則;

(4)挑選合適的後端Web服務器;


可使用下面的終止語句,即經過return()向Varnish返回的指示操做:


1. pass:繞過緩存,即不從緩存中查詢內容或不將內容存儲至緩存中;

 

2. pipe:不對客戶端進行檢查或作出任何操做,而是在客戶端與後端服務器之間創建專用「管道」,

並直接將數據在兩者之間進行傳送;此時,keep-alive鏈接中後續傳送的數據也都將經過此管道進行

直接傳送,並不會出如今任何日誌中;

 

3. lookup:在緩存中查找用戶請求的對象,若是緩存中沒有其請求的對象,後續操做極可能會將其請求的

對象進行緩存;

 

4. error:由Varnish本身合成一個響應報文,通常是響應一個錯誤類信息、重定向類信息或負載均衡器

返回的後端web服務器健康狀態檢查類信息;


vcl_recv也能夠經過精巧的策略完成必定意義上的安全功能,以將某些特定的***扼殺於搖籃中。同時,它也能夠檢查出一些拼寫類的錯誤並將其進行修正等。


Varnish默認的vcl_recv專門設計用來實現安全的緩存策略,它主要完成兩種功能:

(1)僅處理能夠識別的HTTP方法,而且只緩存GET和HEAD方法;

(2)不緩存任何用戶特有的數據;

安全起見,通常在自定義的vcl_recv中不要使用return()終止語句,而是再由默認vcl_recv進行處理,並由其作出相應的處理決策。


下面是一個自定義的使用示例:


sub vcl_recv {

if (req.http.User-Agent ~ "iPad" ||

req.http.User-Agent ~ "iPhone" ||

req.http.User-Agent ~ "Android") {

set req.http.X-Device = "mobile";

} else {

set req.http.X-Device = "desktop";

}

}


此例中的VCL建立一個X-Device請求首部,其值可能爲mobile或desktop,因而web服務器能夠基於此完成不一樣類型的響應,以提升用戶體驗。


[2]vcl_fetch:相對於vcl_recv是根據客戶端的請求做出緩存決策來講,vcl_fetch則是根據服務器端的響應做出緩存決策。在任何VCL狀態引擎中返回的pass操做都將由vcl_fetch進行後續處理。vcl_fetch中有許多可用的內置變量,好比最經常使用的用於定義某對象緩存時長的beresp.ttl變量。經過return()返回給Varnish的操做指示有:


(1)deliver:緩存此對象,並將其發送給客戶端(經由vcl_deliver);

(2)hit_for_pass:不緩存此對象,但能夠致使後續對此對象的請求直接送達到vcl_pass進行處理;

(3)restart:重啓整個VCL,並增長重啓計數;超出max_restarts限定的最大重啓次數後將會返回錯誤信息;

(4)error code [reason]:返回指定的錯誤代碼給客戶端並丟棄此請求;

默認的vcl_fetch放棄了緩存任何使用了Set-Cookie首部的響應。


[3]vcl_pipe:此函數在進入pipe模式時被調用,用於將請求直接傳遞至後端主機,在請求和返回內容沒有改變的狀況下,將不變的內容返回給客戶端,直到整個鏈接被關閉。

此函數通常以以下幾個關鍵字結束:


** error code[reason]

** pipe


[4]vcl_pass:此函數在進入pass模式時被調用,用於將請求直接傳遞至後端主機,後端主機在應答數據後將應答數據發送給客戶端,但不進行任何緩存,在當前鏈接下每次都返回最新的內容。

此函數通常以以下幾個關鍵字結束:


** error code[reason]

** pass


[5]lookup:此模式表示在緩存中查找被請求的對象,而且根據查找的結果交給vcl_hash進行計算,最後把控制權交給函數vcl_hist或函數vcl_miss。


(6)vcl_hash:此函數在進入lookup模式時被調用,在vcl_recv調用後爲請求建立一個hash值時,調用此函數;此hash值將做爲varnish中搜索緩存對象的key;

此函數通常以以下幾個關鍵字結束:


** error code[reason]

** hash


[7]vcl_hit:在執行lookup指令後,在緩存中找到請求的內容後將自動調用該函數。

此函數通常以以下幾個關鍵字結束:



** deliver: 表示將找到的內容發送給客戶端,並把控制權交給函數vcl_deliver.

** error code[reason]

** pass


[8]vcl_miss:在執行lookup指令後,在緩存中沒有找到請求的內容時將自動調用該函數方法,此函數可用於判斷是否須要從後端服務器獲取內容。

此函數通常以以下幾個關鍵字結束:



** fetch: 表示從後端獲取請求的內容,並把控制權交給vcl_fetch函數

** error code[reason]

** pass

[9]vcl_deliver:將在緩存中找到請求的內容發送給客戶端前調用此函數方法。

此函數通常以以下幾個關鍵字結束:


** error code[reason]

** deliver


Varnish處理HTTP請求的過程大體分爲如下幾個步驟:

(1).Receive狀態。也就是請求處理的入口狀態,根據VCL規則判斷該請求應該Pass或Pipe,仍是進入Lookup(本地查詢)

(2).Lookup狀態。進入此狀態後,會在hash表中查找數據,若找到,則進入Hit狀態,不然進入Miss狀態

(3)Pass狀態。在此狀態下,會進入後端請求,即進入Fetch狀態。

(4)Fetch狀態。在Fetch狀態下,對請求進行後端獲取,發送請求,得到數據,並進行本地存儲。

(5)Deliver狀態。將獲取到的數據發送給客戶端,而後完成本次請求。


B.修剪緩存對象

 

一、緩存內容修剪

 

提升緩存命中率的最有效途徑之一是增長緩存對象的生存時間(TTL),可是這也可能會帶來反作用,好比緩存的內容在到達爲其指定的有效期之間已經失效。所以,手動檢驗緩存對象的有效性或者刷新緩存是緩存頗有可能成爲服務器管理員的平常工做之一,相應地,Varnish爲完成這類的任務提供了三種途徑:HTTP 修剪(HTTP purging)、禁用某類緩存對象(banning)和強制緩存未命令(forced cache misses)。

 

這裏須要特殊說明的是,Varnish 2中的purge()操做在Varnish 3中被替換爲了ban()操做,而Varnish 3也使用了purge操做,但爲其賦予了新的功能,且只能用於vcl_hit或vcl_miss中替換Varnish 2中經常使用的set obj.ttl=0s。

 

 

 

在具體執行某清理工做時,須要事先肯定以下問題:

(1)僅須要檢驗一個特定的緩存對象,仍是多個?

(2)目的是釋放內存空間,仍是僅替換緩存的內容?

(3)是否是須要很長時間才能完成內容替換?

(4)這類操做是個平常工做,仍是僅此一次的特殊需求?

 

二、移除單個緩存對象

 

purge用於清理緩存中的某特定對象及其變種(variants),所以,在有着明確要修剪的緩存對象時可使用此種方式。HTTP協議的PURGE方法能夠實現purge功能,不過,其僅能用於vcl_hit和vcl_miss中,它會釋放內存工做並移除指定緩存對象的全部Vary:-變種,並等待下一個針對此內容的客戶端請求到達時刷新此內容。另外,其通常要與return(restart)一塊兒使用。下面是個在VCL中配置的示例。

 

acl purgers {

"127.0.0.1";

"192.168.139.0"/24;

}

sub vcl_recv {

if (req.request == "PURGE") {

if (!client.ip ~ purgers) {

error 405 "Method not allowed";

}

return (lookup);

}

}

sub vcl_hit {

if (req.request == "PURGE") {

purge;

error 200 "Purged";

}

}

sub vcl_miss {

if (req.request == "PURGE") {

purge;

error 404 "Not in cache";

}

}

sub vcl_pass {

if (req.request == "PURGE") {

error 502 "PURGE on a passed object";

}

}

 

客戶端在發起HTTP請求時,只須要爲所請求的URL使用PURGE方法便可,其命令使用方式以下:

# curl -I PURGE http://varniship/path/to/someurl

 

三、強制緩存未命中

 

vcl_recv中使用return(pass)可以強制到上游服務器取得請求的內容,但這也會致使沒法將其緩存。使用purge會移除舊的緩存對象,但若是上游服務器宕機而沒法取得新版本的內容時,此內容將沒法再響應給客戶端。使用req.has_always_miss=ture,可讓Varnish在緩存中搜尋相應的內容但卻老是迴應「未命中」,因而vcl_miss將後續地負責啓動vcl_fetch從上游服務器取得新內容,並以新內容緩存覆蓋舊內容。此時,若是上游服務器宕機或未響應,舊的內容將保持原狀,並可以繼續服務於那些未使用req.has_always_miss=true的客戶端,直到其過時失效或由其它方法移除。

 

四、Banning

 

ban()是一種從已緩存對象中過濾(filter)出某此特定的對象並將其移除的緩存內容刷新機制,不過,它並不阻止新的內容進入緩存或響應於請求。在Varnish中,ban的實現是指將一個ban添加至ban列表(ban-list)中,這能夠經過命令行接口或VCL實現,它們的使用語法是相同的。ban自己就是一個或多個VCL風格的語句,它會在Varnish從緩存哈希(cache hash)中查找某緩存對象時對搜尋的對象進行比較測試,所以,一個ban語句就是相似匹配全部「以/downloads開頭的URL」,或「響應首部中包含nginx的對象」。例如:

ban req.http.host == "magedu.com" && req.url ~ "\.gif$"


定義好的全部ban語句會生成一個ban列表(ban-list),新添加的ban語句會被放置在列表的首部。緩存中的全部對象在響應給客戶端以前都會被ban列表檢查至少一次,檢查完成後將會爲每一個緩存建立一個指向與其匹配的ban語句的指針。Varnish在從緩存中獲取對象時,老是會檢查此緩存對象的指針是否指向了ban列表的首部。若是沒有指向ban列表的首部,其將對使用全部的新添加的ban語句對此緩存對象進行測試,若是沒有任何ban語句可以匹配,則更新ban列表。

 

ban這種實現方式持反對意見有有之,持同意意見者亦有之。反對意見主要有兩種,一是ban不會釋放內存,緩存對象僅在有客戶端訪問時被測試一次;二是若是緩存對象曾經被訪問到,但卻不多被再次訪問時ban列表將會變得很是大。同意的意見則主要集中在ban可讓Varnish在恆定的時間內完成向ban列表添加ban的操做,例如在有着數百萬個緩存對象的場景中,添加一個ban也只須要在恆定的時間內便可完成。其實現方法本處再也不詳細說明。

 

C.Varnish檢測後端主機的健康狀態

 

Varnish能夠檢測後端主機的健康狀態,在斷定後端主機失效時能自動將其從可用後端主機列表中移除,而一旦其從新變得可用還能夠自動將其設定爲可用。爲了不誤判,Varnish在探測後端主機的健康狀態發生轉變時(好比某次探測時某後端主機忽然成爲不可用狀態),一般須要連續執行幾回探測均爲新狀態纔將其標記爲轉換後的狀態。

 

每一個後端服務器當前探測的健康狀態探測方法經過.probe進行設定,其結果可由req.backend.healthy變量獲取,也可經過varnishlog中的Backend_health查看或varnishadm的debug.health查看。

 

backend web1 {

.host = "www..com";

.probe = {

.url = "/.healthtest.html";

.interval = 1s;

.window = 5;

.threshold = 2;

}

}

 

.probe中的探測指令經常使用的有:

(1) .url:探測後端主機健康狀態時請求的URL,默認爲「/」;

(2) .request: 探測後端主機健康狀態時所請求內容的詳細格式,定義後,它會替換.url指定的探測方式;好比:

.request =

"GET /.healthtest.html HTTP/1.1"

"Host: www..com"

"Connection: close";

(3) .window:設定在斷定後端主機健康狀態時基於最近多少次的探測進行,默認是8;

(4) .threshold:在.window中指定的次數中,至少有多少次是成功的才斷定後端主機正健康運行;默認是3;

(5) .initial:Varnish啓動時對後端主機至少須要多少次的成功探測,默認同.threshold;

(6) .expected_response:指望後端主機響應的狀態碼,默認爲200;

(7) .interval:探測請求的發送週期,默認爲5秒;

(8) .timeout:每次探測請求的過時時長,默認爲2秒;

 

所以,如上示例中表示每隔1秒對此後端主機www.RS.com探測一次,請求的URL爲http://www.RS.com/.healthtest.html,在最近5次的探測請求中至少有2次是成功的(響應碼爲200)就斷定此後端主機爲正常工做狀態。

 

若是Varnish在某時刻沒有任何可用的後端主機,它將嘗試使用緩存對象的「寬容副本」(graced copy),固然,此時VCL中的各類規則依然有效。所以,更好的辦法是在VCL規則中判斷req.backend.healthy變量顯示某後端主機不可用時,爲此後端主機增大req.grace變量的值以設定適用的寬容期限長度。

 

D.Varnish使用多臺後端主機

 

Varnish中可使用director指令將一個或多個近似的後端主機定義爲一個邏輯組,並能夠指定的調度方式(也叫挑選方法)來輪流將請求發送至這些主機上。不一樣的director可使用同一個後端主機,而某director也可使用「匿名」後端主機(在director中直接進行定義)。每一個director都必須有其專用名,且在定義後必須在VCL中進行調用,VCL中任何能夠指定後端主機的位置都可以按需將其替換爲調用某已定義的director。

 

backend web1 {

.host = "backweb1.RS.com";

.port = "80";

}

 

director webservers random {

  .retries = 5;

  {

    .backend = web1;

    .weight  = 2;

  }

  {

    .backend  = {

      .host = "backweb2.RS.com";

  .port = "80";

    }

  .weight         = 3;

  }

}

 

如上示例中,web1爲顯式定義的後端主機,而webservers這個directors還包含了一個「匿名」後端主機(backweb2.RS.com)。webservers從這兩個後端主機中挑選一個主機的方法爲random,即以隨機方式挑選。

 

Varnish的director支持的挑選方法中比較簡單的有round-robin和random兩種。其中,round-robin類型沒有任何參數,只須要爲其指定各後端主機便可,挑選方式爲「輪叫」,並在某後端主機故障時再也不將其視做挑選對象;random方法隨機從可用後端主機中進行挑選,每個後端主機都須要一個.weight參數以指定其權重,同時還能夠director級別使用.retires參數來設定查找一個健康後端主機時的嘗試次數。

 

Varnish 2.1.0後,random挑選方法又多了兩種變化形式clienthashclient類型的director使用client.identity做爲挑選因子,這意味着client.identity相同的請求都將被髮送至同一個後端主機。client.identity默認爲cliet.ip,但也能夠在VCL中將其修改成

所須要的標識符。相似地,hash類型的director使用hash數據做爲挑選因子,這意味着對同一個URL的請求將被髮往同一個後端主機,其經常使用於多級緩存的場景中。然而,不管是client還hash,當其傾向於使用後端主機不可用時將會從新挑選新的後端其機。


E.varnish管理進階

 

一、可調參數

 

Varnish有許多參數,雖然大多數場景中這些參數的默認值均可以工做得很好,然而特定的工做場景中要想有着更好的性能的表現,則須要調整某些參數。能夠在管理接口中使用param.show命令查看這些參數,而使用param.set則能修改這些參數的值。然而,在命令行接口中進行的修改不會保存至任何位置,所以,重啓varnish後這些設定會消失。此時,能夠經過啓動腳本使用-p選項在varnishd啓動時爲其設定參數的值。然而,除非特別須要對其進行修改,保持這些參數爲默認值能夠有效下降管理複雜度。

 

二、共享內存日誌

 

共享內存日誌(shared memory log)一般被簡稱爲shm-log,它用於記錄日誌相關的數據,大小爲80M。varnish以輪轉(round-robin)的方式使用其存儲空間。通常不須要對shm-log作出更多的設定,但應該避免其產生I/O,這可使用tmpfs實現,其方法爲在/etc/fstab中設定一個掛載至/var/lib/varnish目錄(或其它自定義的位置)臨時文件系統便可。

 

三、線程模型(Trheading model)

 

varnish的child進程由多種不一樣的線程組成,分別用於完成不一樣的工做。例如:

cache-worker線程: 每鏈接一個,用於處理請求;

cache-main線程:  全局只有一個,用於啓動cache;

ban lurker線程:  一個,用於清理bans;

acceptor線程:    一個,用於接收新的鏈接請求;

epoll/kqueue線程: 數量可配置,默認爲2,用於管理線程池;

expire線程 一個, 用於移除老化的內容;

backend poll線程: 每一個後端服務器一個,用於檢測後端服務器的健康情況;

 

在配置varnish時,通常只需爲關注cache-worker線程,並且也只能配置其線程池的數量,而除此以外的其它均非可配置參數。與此同時,線程池的數量也只能在流量較大的場景下才須要增長,並且經驗代表其多於2個對提高性能並沒有益處。

 

四、線程相關的參數(Threading parameters)

 

varnish爲每一個鏈接使用一個線程,所以,其worker線程的最大數決定了varnish的併發響應能力。下面是線程池相關的各參數及其配置:

 

thread_pool_add_delay      2 [milliseconds]

thread_pool_add_threshold     2 [requests]

thread_pool_fail_delay       200 [milliseconds]

thread_pool_max            500 [threads]

thread_pool_min            5 [threads]

thread_pool_purge_delay      1000 [milliseconds]

thread_pool_stack          65536 [bytes]

thread_pool_timeout         120 [seconds]

thread_pool_workspace      16384 [bytes]

thread_pools              2 [pools]

thread_stats_rate          10 [requests]

 

其中最關鍵的當屬thread_pool_max和thread_pool_min,它們分別用於定義每一個線程池中的最大線程數和最少線程數。所以,在某個時刻,至少有thread_pool_min*thread_pools個worker線程在運行,但至多不能超出thread_pool_max*thread_pools個。根據須要,這兩個參數的數量能夠進行調整,varnishstat命令的n_wrk_queued能夠顯示當前varnish的線程數量是否足夠,若是隊列中始終有很多的線程等待運行,則能夠適當調大thread_pool_max參數的值。但通常建議每臺varnish服務器上最多運行的worker線程數不要超出5000個。

 

 

當某鏈接請求到達時,varnish選擇一個線程池負責處理此請求。而若是此線程池中的線程數量已經達到最大值,新的請求將會被放置於隊列中或被直接丟棄。默認線程池的數量爲2,這對最繁忙的varnish服務器來講也已經足夠。

 


 

F.Varnish的命令行工具

 

一、varnishadm命令

 

命令語法:varnishadm [-t timeout] [-S secret_file] [-T address:port] [-n name] [command [...]]

 

經過命令行的方式鏈接至varnishd進行管理操做的工具,指定要鏈接的varnish實例的方法有兩種:

-n name —— 鏈接至名稱爲「name」的實例;

-T address:port —— 鏈接至指定套接字上的實例;

 

其運行模式有兩種,當不在命令行中給出要執行的"command"時,其將進入交互式模式;不然,varnishadm將執行指定的"command"並退出。要查看本地啓用的緩存,可以使用以下命令進行。

# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082 storage.list




vcl配置常見變量

   

一、在任何引擎中都可使用:


now, .host, .port


二、用於處理請求階段:


client.ip, server.hostname, server.ip, server.port


req.request:請求方法


req.url: 請求的URL


req.proto: HTTP協議版本


req.backend: 用於服務這次請求的後端主機;


req.backend.healthy: 後端主機健康狀態;


req.http.HEADER: 引用請求報文中指定的首部;


req.can_gzip:客戶端是否可以接受gzip壓縮格式的響應內容;


req.restarts: 此請求被重啓的次數;




三、varnish向backend主機發起請求前可用的變量


bereq.request: 請求方法


bereq.url:請求url


bereq.proto:請求協議


bereq.http.HEADER:請求首部


bereq.connect_timeout: 等待與be創建鏈接的超時時長



四、backend主機的響應報文到達本主機(varnish)後,將其放置於cache中以前可用的變量


beresp.do_stream: 流式響應;


beresp.do_gzip:是否壓縮以後再存入緩存;


beresp.do_gunzip:是否解壓縮以後存入緩存


beresp.http.HEADER:報文首部;


beresp.proto: 協議


beresp.status:響應狀態碼


beresp.response:響應時的緣由短語


beresp.ttl:響應對象剩餘的生存時長,單位爲second;


beresp.backend.name: 此響應報文來源backend名稱;


beresp.backend.ip:後端主機ip


beresp.backend.port:後端主機的端口


beresp.storage:



五、緩存對象存入cache以後可用的變量


obj.proto:協議


obj.status:狀態


obj.response:響應報文


obj.ttl:生存週期


obj.hits:命中


obj.http.HEADER:http首部



六、在決定對請求鍵作hash計算時可用的變量


req.hash:將請求交給hash



七、在爲客戶端準備響應報文時可用的變量


resp.proto:協議


resp.status:狀態


resp.response:響應


resp.http.HEADER:http首部


各變量可用的狀態引擎

技術分享



實驗環境

 node2 192.168.139.4

 node4 192.168.139.8

 node5 192.168.139.9


 node1安裝Varnish,gcc做爲緩存服務器

 node4|node5安裝httpd,做爲web服務器



[root@node2 ~]# yum -y install varnish #本機gcc已近安裝

[root@node4 ~]# service httpd start

[root@node5 ~]# service httpd start

編輯varnish的啓動配置文件以前先保存一份

[root@node2 varnish]# cp  /etc/sysconfig/varnish /etc/sysconfig/varnish.bak1

[root@node2 ~]# vim /etc/sysconfig/varnish 

# Configuration file for varnish

#

# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this

# shell script fragment.

#


NFILES=131072 #定義能夠打開的最大文件數量

MEMLOCK=82000 #定義log信息使用多大的內存空間


RELOAD_VCL=1 #

VARNISH_VCL_CONF=/etc/varnish/default.vcl #定義VCL的主配置文件

VARNISH_LISTEN_PORT=80 #定義監聽的端口默認爲80,默認爲6082


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=1 #varnish的最小進程數



VARNISH_MAX_THREADS=1000 #varnish的最大進程數


VARNISH_THREAD_TIMEOUT=120 #定義varnish的工做進程的超時時長


#VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin #緩存文件的存儲類型和緩存路徑,能夠定                                              義爲使用內存存儲


#VARNISH_STORAGE_SIZE=1G #定義varnish的緩衝空間的大小

#VARNISH_STORAGE="maloc,256M" #定義之內存的方式緩存,緩存空間大小爲256M

VARNISH_STORAGE="file,/var/lib/varnish/varnish_storage.bin,1G"#定義緩存以單個文件存儲,不支持持久機制


VARNISH_TTL=120  #定義緩存時長


DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \ #啓動命令

             -f ${VARNISH_VCL_CONF} \

             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \

             -t ${VARNISH_TTL} \

             -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \

VARNISH_USER=varnish    #主進程所使用的用戶

VARNISH_GROUP=varnish    #主進程所使用的組

#DAEMON_OPTS="-p thread_pool_min=5 -p thread_pool_max=500 -p thread_pool_timeout=300"

加這條配置後varnish啓動不了

[root@node1 varnish]# service varnish start

Starting varnish HTTP accelerator:                         [  OK  ]



VCL配置文件的說明

vcl_recv    接收請求 

cacheable    判斷是否爲可緩存對象

incache     判斷hash後的結果是否存在

vcl_hash    可緩存對象hash計算

vcl_hit     緩存中命中

vcl_miss     緩存中未命中

vcl_fetch    獲取後端內容

vcl_deliver   構建緩存發送

vcl_pipe     客戶端請求的方法不是常見方法時,直接交給後端服務器處理

vcl_pass     不檢查緩存直接從後端服務器取

vcl_error    varnish直接返回錯誤響應


[root@node2 ~]# cd /etc/varnish/

[root@node2 varnish]# vim default.vcl

backend default {

  .host = "192.168.139.9";

  .port = "80";

}



wKioL1hk8TLwRq1dAABdoJTwWp0647.png

刷新一次看響應報文Status Code: 304 Not Modified



    1. Request URL:

      http://192.168.139.4/

    2. Request Method:

      GET

    3. Status Code:


      304 Not Modified

    4. Remote Address:

      192.168.139.4:80

  1. Response Headersview source

    1. Connection:

      keep-alive

    2. Date:

      Thu, 29 Dec 2016 11:17:25 GMT

    3. ETag:

      "dff01-23-544ca2bd6b91f"

    4. Last-Modified:

      Thu, 29 Dec 2016 11:13:13 GMT

    5. Via:

      1.1 varnish

    6. X-Varnish:

      1600444971


配置Varnish VCL策略配置文件,實現添加響應報文首部

[root@node2 varnish]# vim test1.vcl 


backend web1 {  --定義後端主機

  .host = "192.168.139.8";

  .port = "80"; --定義後端主機監聽端口

}


sub vcl_deliver { --在vcl_deliver狀態引擎中定義

     if (obj.hits > 0) { 

       set resp.http.X-Cache = "HIT"; --若是緩存命中次數大於0,則添加響應首部X-Cache;設置值爲HIT,我實驗時"HIT " + server.ip;會報錯,已醉

     } else {

       set resp.http.X-Cache = "MISS"; --不然,設置值爲MISS

     }

       return (deliver); --定義返回狀態

}


[root@node2 varnish]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082

200 199     

-----------------------------

Varnish Cache CLI 1.0

-----------------------------

Linux,2.6.32-573.el6.x86_64,x86_64,-sfile,-hcritbit


Type 'help' for command list.

Type 'quit' to close CLI session.


vcl.load test1 /etc/varnish/test1.vcl  #載入配置文件進行編譯爲二進制格式

200 13      

VCL compiled.


vcl.list                   #列出全部的vcl配置文件

200 47      

active         1 boot     #這個是default.vcl文件中的配置,active表示正在被使用

available       0 test1  #剛剛用vcl.load編譯成二進制的vcl配置,available表示可以使用的


vcl.use test1     #應用新的配置test1

200 0        #顯示200 0則應用成功



wKiom1hl8XLzAtWfAABWfOTE0ZY984.png

wKiom1hl8gfx1br0AABNcJzpcQ8320.png

第一次顯示爲MISS(未命中),再刷新

wKioL1hl8k-xwD7XAABWfOTE0ZY633.png

wKiom1hl8YWwzzjMAABMTHTSEr4418.png

顯示HIT(命中)

可是過一會後再刷新,有是MISS,說明緩存已通過期

wKiom1hl89vhBobwAABMoD_y6XQ001.png



  1. [root@node2 varnish]# vim test1.vcl 

新加入如下內容

 

sub vcl_fetch {                      --在vcl.fetch狀態引擎定義

  if (bereq.http.Set-Cookie) {       --若是varnish請求有cookies信息

     unset bereq.http.Set-Cookie;    --則將cookie信息清除(對cookie信息不進行緩存)

     set beresp.ttl = 120s;          --設置緩存時長爲120s

  }

  return (deliver);                  --定義返回狀態

}

[root@node2 varnish]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082

200 199     

-----------------------------

Varnish Cache CLI 1.0

-----------------------------

Linux,2.6.32-573.el6.x86_64,x86_64,-sfile,-hcritbit


Type 'help' for command list.

Type 'quit' to close CLI session.


vcl.load test2 /etc/varnish/test1.vcl 

200 13      

VCL compiled.

vcl.list

200 71      

available       0 boot

active         3 test1

available       0 test2


vcl.show test2     #能夠直接查看顯示配置的vcl

200 436     

backend web1 {    

  .host = "192.168.139.8";    

  .port = "80";             

}

 

sub vcl_deliver {       

     if (obj.hits > 0) {   

       set resp.http.X-Cache = "HIT";

     } else {

       set resp.http.X-Cache = "MISS"; 

     }

       return (deliver);   

}

 

sub vcl_fetch {             

  if (bereq.http.Set-Cookie) { 

     unset bereq.http.Set-Cookie; 

     set beresp.ttl = 120s;      

  }

  return (deliver);             

}

vcl.use test2 #使用test2的配置

200 0   


測試

[root@node2 varnish]# curl -I http://192.168.139.4

HTTP/1.1 200 OK

Server: Apache/2.2.15 (CentOS)

Last-Modified: Thu, 29 Dec 2016 11:12:44 GMT

ETag: "dff0b-22-544ca2a1ed862"

Content-Type: text/html; charset=UTF-8

Content-Length: 34

Date: Fri, 30 Dec 2016 05:50:39 GMT

X-Varnish: 1531569619

Age: 0

Via: 1.1 varnish

Connection: keep-alive

X-Cache: MISS   #緩存未命中且Age;0


[root@node2 varnish]# curl -I http://192.168.139.4

HTTP/1.1 200 OK

Server: Apache/2.2.15 (CentOS)

Last-Modified: Thu, 29 Dec 2016 11:12:44 GMT

ETag: "dff0b-22-544ca2a1ed862"

Content-Type: text/html; charset=UTF-8

Content-Length: 34

Date: Fri, 30 Dec 2016 05:50:49 GMT

X-Varnish: 1531569620 1531569619

Age: 10

Via: 1.1 varnish 

Connection: keep-alive

X-Cache: HIT   #緩存命中,且緩存開始計時Age:10



配置Varnish VCL策略配置文件,利用varnish自帶着函數(purge)清空緩存

[root@node2 varnish]# vim test1.vcl 

新加入如下內容


acl purge {            --定義ACL訪問名稱
   "localhost" ;         --受權本地主機容許訪問
   "127.0.0.1" ;         --受權127.0.0.1容許訪問
   "192.168.139.0" /24 ;     --受權192.168.139.0/24網段 內主機訪問
}
 
--如下設定,當發送PURGE請求的客戶端不是在acl中設定的地址時,將返回405狀態代碼,提示Not allowed.
--當請求的URL是以.php和.cgi結尾時,則交給後端服務器處理響應
sub vcl_recv {
   if  (req.request ==  "PURGE" ) {
       if  (!client.ip ~ purge) {
       error 405  "Not allowed." ;
    }
       elseif(req.url ~  "\.(php|cgi($|\?))" ){
       return  (pass);
    }
       else  {
       return  (lookup);
    }
   }
}
 
sub vcl_hit {                    --在vcl_hit狀態引擎中定義策略
   if  (req.request ==  "PURGE" ) {  --若是緩存命中且請求方法爲 "PURGE"
    purge;                        --執行內置函數purge  
    error 200  "Purged" ;           --返回信息及狀態碼
 
}
 
sub vcl_miss {                    --在vcl_miss中定義策略
   if  (req.request ==  "PURGE" ) {   --若是請求方法 "PURGE" 沒有命中
    purge;                         --執行內置函數purge
    error 200  "no cache." ;         --返回信息及狀態碼
   }
}
 
sub vcl_pass {                            --在vcl_pass中定義策略
   if  (req.request ==  "PURGE" ) {
    error 502  "Purged on a passed object." ;
  }
}


在作實驗時vcl.load加載vcl配置時在hit和miss段總是提醒錯誤,錯誤以下

Expected '(' got ';'(program line 324), at(input Line 44 Pos 9) purge;     



只有把 purge; 去掉才能夠,反正我已醉 看不出來錯       


vcl.load -> vcl.use 後測試

[root@node2 varnish]# curl -I http://192.168.139.4

HTTP/1.1 200 OK

Server: Apache/2.2.15 (CentOS) 

Last-Modified: Thu, 29 Dec 2016 11:12:44 GMT

ETag: "dff0b-22-544ca2a1ed862"

Content-Type: text/html; charset=UTF-8

Content-Length: 34

Date: Fri, 30 Dec 2016 07:40:26 GMT

X-Varnish: 1531569643 1531569642 

Age: 31

Via: 1.1 varnish

Connection: keep-alive

X-Cache: HIT   #能夠命中,且Age:31


[root@node2 varnish]# curl -I -X http://192.168.139.4

curl: no URL specified!

curl: try 'curl --help' or 'curl --manual' for more information

[root@node2 varnish]# curl -I -X PURGE  http://192.168.139.4

HTTP/1.1 200 Purged #協議/版本號 狀態碼(200) 請求方式

Server: Varnish  

Retry-After: 0

Content-Type: text/html; charset=utf-8

Content-Length: 380

Date: Fri, 30 Dec 2016 07:41:51 GMT

X-Varnish: 1531569644

Age: 0      #Age: 0

Via: 1.1 varnish

Connection: close

X-Cache: MISS #不能命中(此時緩存本應該還沒過時,應該命中),curl請求時用PURGE時vcl的配置將緩存清理了

相關文章
相關標籤/搜索