http請求報文頭部vary信息


 原文出自http://mark.koli.ch/2010/09/understanding-the-http-vary-header-and-caching-proxies-squid-etc.html
作者是Mark S. Kolich

就是簡單的對vary進行一下介紹,方便大家理解,下面是一個簡單的翻譯

我從來沒有過多關注http的vary header。事實上,我非常幸運在過去的很長時間避開了它給我帶來的問題,所以就沒引起我的關注,但是,如果你最終要配置一個高性能的反向代理服務器,那么理解vary header並且它對於你的緩存策略意味着什么事非常有必要的。
下面是一個關於我最近處理關於squid,apache的一個有趣的問題,並且這個問題很難找出竟然是和vary response header有關。
 

1 關於vary的一些基本信息

 

流行的緩存代理服務器,像squid,通常會根據請求的URI和vary response header的內容產生一個hash值。當緩存服務器接收到一個請求的時候,它會根據輸入產生一個hash,之后檢查緩存看是否已經有這個資源在硬盤上或者在內存中匹配這個hash值。緩存服務器以此來判斷命中與否。
而vary response header告訴緩存服務器使用什么判斷一個請求的資源是fresh還是stale的,一個簡單的vary header包括:
 
Vary: Accept-Encoding 
Vary: Accept-Encoding,User-Agent 
Vary: X-Some-Custom-Header,Host 
Vary: * 

  

根據http標准,vary 的值表明需要哪些request header去充分決定一個response是否是fresh的,緩存服務器是否可以不用重新確認就使用一個reponse。
 

2 緩存遇到的問題

 

我配置squid作為一個輪詢的負載均衡服務器和一個反向代理緩存服務器,在apache服務器的前面,每個apache服務器都運行着我的web應用,我嚴格配置squid緩存.json文件24個小時。
我打開了一個web瀏覽器,我訪問了一個我認為已經被緩存的URL。
 
GET /path/big.json HTTP/1.1 
Host: app.kolich.local 
User-Agent: Firefox 
 
HTTP/1.0 200 OK 
Date: Fri, 24 Sep 2010 23:09:32 GMT 
Content-Type: application/json;charset=UTF-8 
Content-Language: en-US 
Vary: Accept-Encoding,User-Agent 
Age: 1235 
X-Cache: HIT from cache.kolich.local 
X-Cache-Lookup: HIT from cache.kolich.local:80 
Content-Length: 25090 
Connection: close 
很好,它已經被緩存了,然后我在另一台機器上打開了第二個web瀏覽器(注:是一個不同類型的瀏覽器),這一次,注意一下X-Cache:MISS
 
GET /path/big.json HTTP/1.1 
Host: app.kolich.local 
User-Agent: Chrome 
 
HTTP/1.0 200 OK 
Date: Fri, 24 Sep 2010 23:11:45 GMT 
Content-Type: application/json;charset=UTF-8 
Content-Language: en-US 
Vary: Accept-Encoding,User-Agent 
Age: 4 
X-Cache: MISS from cache.kolich.local 
X-Cache-Lookup: MISS from cache.kolich.local:80 
Content-Length: 25090 
Connection: close 

 

wow,看看它,我請求了一個完全一樣的資源,只是從一個不同的瀏覽器上,現在我看到了一個MISS。這肯定不是我想看到的結果,我當然需要需要同樣的緩存對象而無論到底是誰請求了這個資源。如果就這樣放着的話,這個緩存服務器只會是一個每一個瀏覽器都會有一份拷貝的緩存,而不是一個全局的緩存。
 

3 解決方案,檢查你的vary header

 

觀察上面兩個請求,注意User-Agent header和Vary header,雖然兩個請求都是請求同一個資源,但是squid把這個兩個請求看做是不同的了,這是怎么發生的呢,我們看一下Vary header:
 
Vary: Accept-Encoding,User-Agent 
它告訴squid請求的URI,Accept-Encoding header和User-Agent header應該包括在hash值內去決定在緩存上的對象是可用的。很明顯的,任何一個(URI, Accept-Encoding,"Firefox")組合的hash值和(URI, Accept-Encoding, "Chrome")組合產生的hash值都是不匹配的,所以squid才認為這兩個請求是請求不同的內容的。
為了解決這個問題,我找到了煩人的附加在我的Vary response header上的User-Agent是從哪來的,原來是在apache自帶的mod_deflate模塊,推薦的mod_deflate的配置包括如果一個response沒有被mod_deflate壓縮話就默認附加User-Agent在Vary header后面。這是推薦的apache配置中關於mod_deflate的相關行:
 
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary 
Header append Vary User-Agent env=!dont-vary 

 

我刪除掉了上面的這兩行,重啟了apache然后squid會忽略掉請求的瀏覽器客戶端的類型。本質上說,我通過移除Vary header中的User-Agent告訴squid不要再去關心用戶的瀏覽器類型,然后問題就解決了。
 
轉載自http://shunter.blog.51cto.com/2183398/1076521


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM