2016-07-28 45 views
0

我有一個清漆緩存(版本4),後端有時變成「慢」。我使用運行狀況檢查來強制清漆在緩存中「緩慢」以不飽和時從緩存中提供陳舊內容。爲什麼有這麼多通過清漆?

所以MI後端定義:

backend api { 
    .host = "111.111.111.111"; 
    .port = "80"; 
    .first_byte_timeout = 300s; 
    .probe = { 
      .url = "/some/url"; 
      .expected_response = 200; 
      .timeout = 80ms; 
      .interval = 120s; 
      .window = 1; 
      .threshold = 1; 
    } 

}

backend apibackup { 
    .host = "111.111.111.111"; 
    .port = "80"; 
    .first_byte_timeout = 300s; 
    .probe = { 
      .url = "/some/url"; 
      .expected_response = 200; 
      .timeout = 80ms; 
      .interval = 120s; 
      .window = 1; 
      .threshold = 1; 
    } 

}

,並配置寬限模式:

sub vcl_hit { 
    if (obj.ttl > 0s) { 
      # A standard hit, deliver from cache 
      return (deliver); 
    } 
    elsif (std.healthy(req.backend_hint)) { 
      if (obj.ttl + 30s > 0s) { 
        # page expired within a limited grace time and backend 
        # is healthy: deliver from cache while cache is updated 
        # asynchronous 
        return (deliver); 
      } else { 
        # page expired too long ago - fetch from backend 
        return (fetch); 
      } 
    } 
    else { 
      if (obj.ttl + obj.grace > 0s) { 
        # backend is not healthy - provide the page from cache 
        # during full grace time set in vcl_backend_response 
        return (deliver); 
      } else { 
        # page expired for the full grace time and backend is 
        # considered unhealthy - try to contact the backend 
        # anyway 

        return (fetch); 
      } 
    } 

}

但是,只有使用此配置,如果後端生病並且對象在緩存中不存在,varnish將返回503(並且我想從後端獲取)。爲了避免這種情況,我必須把同樣的conf在vcl_miss迫使漆從「生病」後臺抓取內容:

sub vcl_miss{ 

    if (std.healthy(req.backend_hint)) { 
        return (fetch); 
      } 
    else { 
        set req.backend_hint = apibackup; 
        return (fetch); 
      } 

}

這種方式,如預期的結果,當後端是緩慢的,清漆會從緩存中提供陳舊的內容,並且響應時間會得到改善。

但是,我發現現在我有更多的「通過」請求。要求,當然,清漆應該緩存(並且在它之前)。 Aprox * 100更多。所以我解決了一個問題,但我創造了另一個問題。

Cookie未設置(在recv和後端響應中),強制清漆進行緩存。

unset beresp.http.set-cookie; 

unset req.http.Cookie; 

所以,我的問題是...爲什麼我有很多通行證要求?那我該怎麼避免呢?

回答

0

但僅此配置,如果後端是病人和 對象不存在於緩存中,清漆返回503(我想 從後端獲取)。爲了避免這種情況,我必須把同樣的conf 在vcl_miss迫使漆從「生病」後臺抓取內容:

...

我認爲這個假設是錯誤的。 vcl_miss子程序相當於內置的一個;你總是執行return (fetch)。當寬限期內容不可用時,添加該代碼不會強制Varnish使用噁心的後端。事實上,據我所知,你不能強迫Varnish使用一個噁心的後端。

我已經創建了一個玩具清漆測試用例來表明使用該代碼沒有任何變化。當寬限期內容不可用時,清漆永遠不會使用噁心的後端,因此它會向客戶端發送503響應。

varnishtest "" 

server s1 { 
    rxreq 
    expect req.url == "/1" 
    txresp -body "foo" 
} -start 

varnish v1 -vcl+backend { 
    import std; 

    sub vcl_hit { 
     if (obj.ttl > 0s) { 
      return (deliver); 
     } 
     elsif (std.healthy(req.backend_hint)) { 
      return (deliver); 
     } 
     else { 
      if (obj.ttl + obj.grace > 0s) { 
       return (deliver); 
      } else { 
       return (fetch); 
      } 
     } 
    } 

    # XXX: nonsense subroutine equivalent to the build-in one just to show this 
    # doesn't force Varnish to fetch contents from sick backends. 
    sub vcl_miss{ 
     if (std.healthy(req.backend_hint)) { 
      return (fetch); 
     } else { 
      return (fetch); 
     } 
    } 

    sub vcl_backend_response { 
     set beresp.ttl = 1s; 
     set beresp.grace = 1s; 
    } 
} -start 

client c1 { 
    txreq -url "/1" 
    rxresp 
    expect resp.status == 200 
    expect resp.bodylen == 3 
} -run 

varnish v1 -cliok "backend.set_health s1 sick" 

delay 1.5 

client c1 { 
    txreq -url "/1" 
    rxresp 
    expect resp.status == 200 
    expect resp.bodylen == 3 
} -run 

delay 1.0 

client c1 { 
    txreq -url "/1" 
    rxresp 
    expect resp.status == 503 

    txreq -url "/2" 
    rxresp 
    expect resp.status == 503 
} -run 

更新測試用例:

varnishtest "" 

server s1 { 
    rxreq 
    expect req.url == "/1" 
    txresp -body "foo" 

    rxreq 
    expect req.url == "/1" 
    txresp -body "foobar" 

    rxreq 
    expect req.url == "/2" 
    txresp -body "hello" 
} -start 

varnish v1 -vcl { 
    import std; 

    backend default { 
     .host = "${s1_addr}"; 
     .port = "${s1_port}"; 
    } 

    backend backup { 
     .host = "${s1_addr}"; 
     .port = "${s1_port}"; 
    } 

    sub vcl_hit { 
     if (obj.ttl > 0s) { 
      return (deliver); 
     } 
     elsif (std.healthy(req.backend_hint)) { 
      return (deliver); 
     } 
     else { 
      if (obj.ttl + obj.grace > 0s) { 
       return (deliver); 
      } else { 
       return (fetch); 
      } 
     } 
    } 

    sub vcl_miss{ 
     if (!std.healthy(req.backend_hint)) { 
      set req.backend_hint = backup; 
     } 
     return (fetch); 
    } 

    sub vcl_backend_response { 
     set beresp.ttl = 1s; 
     set beresp.grace = 1s; 
    } 
} -start 

client c1 { 
    txreq -url "/1" 
    rxresp 
    expect resp.status == 200 
    expect resp.bodylen == 3 
} -run 

varnish v1 -cliok "backend.set_health default sick" 

delay 1.5 

client c1 { 
    txreq -url "/1" 
    rxresp 
    expect resp.status == 200 
    expect resp.bodylen == 3 
} -run 

delay 1.0 

client c1 { 
    txreq -url "/1" 
    rxresp 
    expect resp.status == 200 
    expect resp.bodylen == 6 

    txreq -url "/1" 
    rxresp 
    expect resp.status == 200 
    expect resp.bodylen == 6 

    txreq -url "/2" 
    rxresp 
    expect resp.status == 200 
    expect resp.bodylen == 5 
} -run 

varnish v1 -expect cache_hit == 2 
varnish v1 -expect cache_hitpass == 0 
+0

對不起,你是對的。我忘記了一點細節。我有一個替代後端(但是是相同的)強制清漆來獲取內容。 –

+0

謝謝!那個細節非常重要:)我已經調整了測試用例來反映你的設置,它按預期工作。我的意思是,內容是從備份後端獲取的,「cache_hitpass」計數器沒有增加。你如何衡量這些'通過'的要求? –