2014-12-04 108 views

回答

0

你可以做漆,stale-while-revalidate類似,但並不完全相同。與前高速緩存中的想法是,當後端發送一個對象到緩存它設置一個Expires頭,將允許高速緩存以提供此內容,而不會打擾後端。如果緩存會檢查每個請求的後端,那麼獲得的速度就不會太快,因爲您最終會在每個請求中等待後端。

要解決這個問題,您應該相應地設置您的Expires標頭,並且/或者清除/禁止網址,如果突然您需要在Expires之前擺脫陳舊的內容。這樣,緩存將從它自己的緩存中發送內容,或者如果它沒有它或已過時,則從後端獲取。

編輯:

我與光油4.0.1測試,支持有條件的請求到後端。

我的測試設置一直是Apache的虛擬主機與ExpiresByType text/html "access plus 5 seconds"

結果:

* << BeReq >> 65539 
- Begin   bereq 65538 bgfetch 
- Timestamp  Start: 1418403624.141695 0.000000 0.000000 
- BereqMethod GET 
- BereqURL  /prueba.html 
- BereqProtocol HTTP/1.1 
- BereqHeader User-Agent: lwp-request/6.03 libwww-perl/6.05 
- BereqHeader X-Forwarded-For: 127.0.0.1 
- BereqHeader Host: localtest 
- BereqHeader Surrogate-Capability: key=ESI/1.0 
- BereqHeader Accept-Encoding: gzip 
- BereqHeader If-Modified-Since: Thu, 01 Dec 2011 10:37:55 GMT 
- BereqHeader If-None-Match: "3e8be5-46-4b30571f606c0" 
- BereqHeader X-Varnish: 65539 
- VCL_call  BACKEND_FETCH 
- VCL_return  fetch 
- Backend  17 vdir server1(127.0.0.1,,80) 
- Timestamp  Bereq: 1418403624.141869 0.000174 0.000174 
- Timestamp  Beresp: 1418403624.143205 0.001510 0.001336 
- BerespProtocol HTTP/1.1 
- BerespStatus 304 
- BerespReason Not Modified 
- BerespHeader Date: Fri, 12 Dec 2014 17:00:24 GMT 
- BerespHeader Server: Apache 
- BerespHeader ETag: "3e8be5-46-4b30571f606c0" 
- BerespHeader Expires: Fri, 12 Dec 2014 17:00:29 GMT 
- BerespHeader Cache-Control: max-age=5 
- TTL   RFC 5 -1 -1 1418403624 1418403624 1418403624 1418403629 5 
- BerespProtocol HTTP/1.1 
- BerespStatus 200 
- BerespReason OK 
- BerespHeader Last-Modified: Thu, 01 Dec 2011 10:37:55 GMT 
- BerespHeader Content-Type: text/html 
- VCL_call  BACKEND_RESPONSE 
- TTL   VCL 5 21600 0 1418403624 
- VCL_return  deliver 
- Storage  malloc s0 
- ObjProtocol HTTP/1.1 
- ObjStatus  200 
- ObjReason  OK 
- ObjHeader  Date: Fri, 12 Dec 2014 17:00:24 GMT 
- ObjHeader  Server: Apache 
- ObjHeader  ETag: "3e8be5-46-4b30571f606c0" 
- ObjHeader  Expires: Fri, 12 Dec 2014 17:00:29 GMT 
- ObjHeader  Cache-Control: max-age=5 
- ObjHeader  Last-Modified: Thu, 01 Dec 2011 10:37:55 GMT 
- ObjHeader  Content-Type: text/html 
- BackendReuse 17 server1(127.0.0.1,,80) 
- Timestamp  BerespBody: 1418403624.143465 0.001770 0.000260 
- Length   70 
- BereqAcct  289 0 289 181 0 181 
- End 

在這裏你可以看到,我問過期的對象,所以清漆去取水的時候,並要求它是這樣的:

- BereqURL  /prueba.html 
- BereqHeader If-Modified-Since: Thu, 01 Dec 2011 10:37:55 GMT 
- BereqHeader If-None-Match: "3e8be5-46-4b30571f606c0" 

後端與解答:

- BerespStatus 304 
- BerespReason Not Modified 
- BerespHeader Date: Fri, 12 Dec 2014 17:00:24 GMT 
- BerespHeader ETag: "3e8be5-46-4b30571f606c0" 
- BerespHeader Expires: Fri, 12 Dec 2014 17:00:29 GMT 
- BerespHeader Cache-Control: max-age=5 

因此,沒有主體的字節傳輸,以及清漆刷新它的對象與最新更新的頭。

也許這就是你想要的行爲。

請記住,一個GET請求不驗證條件(If-Modified-SinceIf-None-Match)將只返回一個304 Not Modified,一些頭部,並且不體(完全一樣,如果它是一個HEAD請求,在相同的條件),如果它不驗證它將返回標題和新的主體。但HEAD請求,不驗證將返回200 OK,和NO正文,迫使你重新請求一個GET。

HTTP/1.1 Method Definitions RFC

HEAD方法是相同,除了在應答服務器不能返回一個消息體得到的。響應HEAD請求HTTP頭中包含的元信息 應該是 與爲響應GET請求而發送的信息相同。

+0

這個想法是在發送給客戶端之前,緩存可以通過HEAD調用檢查每個被請求的資源的etag屬性中的值。通過這種方式,客戶肯定會擁有所請求資源的更新版本。你認爲這是一個好方法嗎?謝謝。 – ced 2014-12-04 12:31:10

+0

據我所知,varnish至少不會默認做到這一點,如果它仍然有效的緩存中的對象。我將發送它自己的緩存版本而不檢查。在每個請求上執行HEAD的問題是,您仍將最終等待後端服務器,那麼,爲什麼要將緩存放在前面? – 2014-12-04 12:34:25

+0

我認爲HEAD不像後端的資源密集型,至少不到GET調用。這個緩存對於不把整個響應從後端發送到客戶端可能是有幫助的,但只是比較資源的新鮮度。我錯了嗎 ? – ced 2014-12-04 12:46:23