2012-03-06 57 views
0

我試圖繞過一個後端服務器,它會不時地開始用200 OK響應來提供空白頁面,讓Varnish繼續提供這些頁面的舊緩存版本(又名。寬限模式)。如何在Varnish緩存中的對象長度爲零時使其失效?

首先,我試着檢查vcl_fetch中的響應,但據我所知,無法找出vcl_fetch中的內容長度。然後,我嘗試在vcl_deliver(其中Content-Length標頭可用)處完成這項工作。這確實有效,但我無法弄清楚如何清除壞的緩存對象(帶有空白頁的那個對象),所以這似乎是不可行的。

有人建議我設置obj.grace和obj.ttl在vcl_deliver,這是我當前的代碼:

sub vcl_deliver { 
    # If the front page is blank, invalidate this cached object, in hope 
    # that we'll get a new one. 
    if (req.url == "/" && std.integer(resp.http.content-length, 0) < 1000) { 
    set obj.grace = 0m; 
    set obj.ttl = 0m; 

    return(restart); 
    } 
} 

然而,光油不喜歡這一點,讓我當我嘗試這個錯誤加載VCL:

Message from VCC-compiler: 
'obj.grace': cannot be set in method 'vcl_deliver'. 
At: ('input' Line 146 Pos 9) 
    set obj.grace = 0m; 
--------#########------ 

我得到同樣的錯誤obj.ttl如果刪除obj.grace一行 - 既不似乎是寫在vcl_deliver,即使the docs say otherwise。這是在光油3.0.2。

回答

0

在vcl_deliver中執行此操作爲時已晚。在將內容發送到客戶端之前調用該子對象,並且obj不再可用(只有'resp'不包含任何ttl或寬限參數)。

您是否嘗試過在vcl_fetch中執行此操作?你不需要調用'restart',而是直接調用'hit_for_pass'。

無論如何,(不確定)我不認爲可以使用寬限模式取決於響應內容,因爲它應該在您無法獲得任何內容更新(後端失敗)時觸發。也許它可以通過將後端更改爲「zombie」並重新啓動請求來工作,但肯定的是,一旦您處於vcl_fetch中,響應將被提取,寬限模式將不會觸發。

+0

的問題是,我不能想出一個辦法弄清楚,如果我們得到了'vcl_fetch'空的響應。 – mikl 2012-04-07 18:54:50

+1

你可以。只需檢查「beresp.http.content-length」而不是「resp」,以便檢查從後端接收的內容,而不是將發送到客戶端的內容。 – 2012-04-19 12:38:55

+0

我認爲你建議的是這樣的: if(!beresp.http.content-length){obj.grace = 5m; } 但這仍然是我的失敗。 – 2013-04-05 20:29:54

2

我所做的就是檢查內容長度爲0和20 sub_vcl_fech並重新啓動時,發生這種情況20

if (beresp.http.Content-Length == "0" || beresp.http.Content-Length == "20"){ 
    return(restart); 
} 

內容長度時發生錯誤,什麼我的服務器返回。

在副vcl_recv

我添加上重啓最大的2

if(req.restarts == 2){ 
    error 500 req.http.host; 
} 

選項2

另一種選擇i。從清漆文檔得到的金額的支票。在像vcl_fetch https://www.varnish-cache.org/docs/3.0/tutorial/handling_misbehaving_servers.html

  1. 投擲錯誤:誤差751 req.http.host;
  2. 在vcl_error中添加魔術標記。
  3. add return(restart);在vcl_error
  4. 您在vcl_recv或vcl_fetch魔法標記組