這兩天在學習varnish,在學到vcl時,不理解pipe和pass的區別以及如何區分加以應用。通過兩天的搜尋,總算是理清了概念。現在記錄在部落格上跟大家分享。
當 vcl_recv 函數接收到請求時,它要判斷如何處理這個請求。有三種情況 :
調用 pass 函數,從後端伺服器調用資料。 調用lookup函數,從緩衝中尋找應答資料並返回,如果尋找不到,則調用pass函數從後端伺服器調用資料 。 調用 pipe 函數,建立用戶端和後端伺服器之間的直接連接,從後端伺服器調用資料。
在這裡,我就有幾個疑惑:
pass和pipe都從後端伺服器取資料,它們之間有什麼不同呢? 什麼情況下用pass,什麼情況下用pipe呢? 什麼樣的資料會被緩衝在varnish中呢?
在理解這幾個問題前,需要先理解另外一些概念:
http 建立串連的過程 http 請求的類型:get post head
先說http建立串連的過程(我唯寫下大概,因為不是本文的重心,具體的請另外上網查):
當瀏覽器想要獲得一個網頁內容時,如在瀏覽器輸入www.google.com。 這時瀏覽器開始跟伺服器建立串連,先執行三向交握,確認建立串連。 之後瀏覽器會發送請求,一個網頁包含多個內容,片,本文,html代碼,css代碼,js代碼。如果在html 1.0版本中,請求一個檔案是需要建立一次串連的,多個請求多個串連。開銷是很大的。而在HTML 1.1中,具有了長串連的特性,允許在keep-live 時間內保持串連,在這段時間內無須再建立串連就可以發送多個請求。 請求完成 或 keep-live時間到限,串連斷開。
HTTP 要求的類型:
HTTP 要求的類型有幾種,下面是主要的幾種:
GET : 請求指定的頁面資訊,並返回實體主體。 HEAD: 只請求頁面的首部。 POST: 請求伺服器接受所指定的文檔作為對所標識的URI的新的從屬實體。
說白了,請求一個靜態HTML頁面就是用get類型,而如果你在新浪微博上發一條微博,其實就是post 類型。
總結來說,get是請求相關URI並接受伺服器的返回資料。為了接收資料。
post是發送資料給伺服器,伺服器需要對這些資料做相應的處理。為了發送資料。
以上都明白的話,就可以解答這三個問題了:
pass和pipe都從後端伺服器取資料,它們之間有什麼不同呢? 什麼情況下用pass,什麼情況下用pipe呢? 什麼樣的資料會被緩衝在varnish中呢?
問:pass和pipe都從後端伺服器取資料,它們之間有什麼不同呢? 答:當vcl_recv調用 pass 函數時,pass將當前請求直接轉寄到後端伺服器。而後續的請求仍然通過varnish處理。 例如,建立了HTTP串連之後,用戶端順序請求 a.css 、a.png兩個檔案,“當前請求”指的是第一個請求,即a.css,a.css被直接轉寄到後端伺服器,不被緩衝。而後續的a.png則再由varnish來做處理,varnish會判斷a.png 如何處理。 總結:一個串連中除了當前請求,其它請求仍然按照正常情況由varnish處理。而pipe模式則不一樣,當vcl_recv判斷 需要調用 pipe 函數時,varnish會在用戶端和伺服器之間建立一條直接的串連 ,之後用戶端的所有請求都直接發送給伺服器,繞過varnish,不再由varnish檢查請求,直到串連斷開。
什麼情況下用pass,什麼情況下用pipe呢? 答:pass 通常只處理靜態頁面。即只在GET 和 HEAD 類型的請求中時才適合調用pass函數。另外,需要注意的一點是,pass模式不能處理POST請求,為什麼呢?因為POST請求一般是發送資料給伺服器,需要伺服器接收資料,並處理資料,反饋資料 。是動態,不作緩衝。 範例程式碼如下: if (req.request !="GET" && req.request != "HEAD") { return (pipe); } 那什麼情況下用pipe?由以上陳述可以知,類型是POST時用pipe,但是也許還不太清晰。舉個例子,當用戶端在請求一個視頻檔案時,或者一個大的文檔,如.zip .tar 檔案,就需要用pipe模式,這些大的檔案是不被緩衝在varnish中的。
什麼樣的資料會被緩衝在varnish中呢?答:varnish只緩衝待用資料。在網上搜到的varnish緩衝策略,可以解答這個問題: varnish緩衝策略 預設是根椐後端返回的http狀態代碼決定是否緩衝。可以緩衝的狀態代碼如下: 200 203 300 301 302 410 404 varnish現在還不支援ranges請求,所以不會緩衝206狀態的結果。 管理員可以在vcl的設定檔中的vcl_fetch部分,加入自已的緩衝策略,方法是修改beresp.cacheable變數。下面的例子,看後端返回中如果設定了cookie,則不緩衝: sub fetch { if (beresp.http.Set-Cookie) { set beresp.cacheable = false; } }
參考文章:
1、Varnish Configuration Language - VCL(varnish配置語言-VCL):http://linuxguest.blog.51cto.com/195664/355220
2、varnish緩衝策略及緩衝時間計算方法說明: http://blog.sina.com.cn/s/blog_5374d6e30100tupo.html