5

EC2 Web服務器網格在ELB負載平衡器後面運行。 ELB支持亞馬遜的CloudFront內容交付網絡。內容分發網絡對我來說是非常新的。我的理解是,CloudFront應該通過在其「邊緣」緩存靜態內容來加速性能。但這不是發生了什麼事。對於未更改的靜態內容,Amazon CloudFront不一致地返回304(未修改)?

考慮一下我的EC2實例,其內容應該始終有五分鐘的生命週期。對於靜態內容,這通常意味着在我的web.config文件中聲明如下:

<staticContent> 
    <clientCache cacheControlCustom="public" cacheControlMode="UseMaxAge" cacheControlMaxAge="00.00:05:00"/> 
</staticContent> 

...和動態的東西,它通常是指對一個HttpResponse對象執行以下命令:

resp.Cache.SetCacheability(HttpCacheability.Public); 
resp.Cache.SetMaxAge(TimeSpan.FromMinutes(5)); 

以此爲背景...

當我的瀏覽器直接點擊ELB時,一切都按預期工作。 Firebug始終如一地顯示,針對存在於瀏覽器緩存中的內容返回304(未修改),已經過了五分鐘過期,但尚未在服務器上進行更改。下面是下載defs.js的響應頭,例如:

HTTP/1.1 304 Not Modified 
Accept-Ranges: bytes 
Cache-Control: public,max-age=300 
Date: Tue, 22 Apr 2014 13:54:16 GMT 
Etag: "0152435d158cf1:0" 
Last-Modified: Tue, 15 Apr 2014 17:36:18 GMT 
Server: Microsoft-IIS/7.5 
X-Powered-By: ASP.NET 
Connection: keep-alive 

IIS正確地看到,該文件還沒有,因爲4月15日改變,並返回304

但是看起來會發生什麼當文件通過CloudFront抓取時。

HTTP/1.1 200 OK 
Content-Type: application/x-javascript 
Content-Length: 205 
Connection: keep-alive 
Accept-Ranges: bytes 
Cache-Control: public,max-age=300 
Date: Tue, 22 Apr 2014 14:07:33 GMT 
Etag: "0152435d158cf1:0" 
Last-Modified: Tue, 15 Apr 2014 17:36:18 GMT 
Server: Microsoft-IIS/7.5 
X-Powered-By: ASP.NET 
Age: 16 
X-Cache: Hit from cloudfront 
Via: 1.1 0f140ef1be762325ad24a7167aa57e65.cloudfront.net (CloudFront) 
X-Amz-Cf-Id: Evfdhs-pxFojnzkQWuG-Ubp6B2TC5xbunhavG8ivXURdp2fw_noXjw== 

在這種情況下CloudFront的強制瀏覽器重新下載整個文件,即使,你可以看到:

(一)是否知悉該文件還沒有被4月15日修改(見尾頁(b)CloudFront確實擁有手頭文件的緩存副本(請參閱X-Cache標頭)

也許您想知道我的瀏覽器是否正在發送有效的If-Modified-Since標頭。它的確是。這裏是請求標題:

GET /code/shared/defs.js HTTP/1.1 
Host: d2fn6fv5a0cu3b.cloudfront.net 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:28.0) Gecko/20100101 Firefox/28.0 
Accept: */* 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
DNT: 1 
Referer: http://d2fn6fv5a0cu3b.cloudfront.net/ 
Connection: keep-alive 
If-Modified-Since: Tue, 15 Apr 2014 17:36:18 GMT 
If-None-Match: "0152435d158cf1:0" 
Cache-Control: max-age=0 

這是一個奇怪的情況。如果我只是坐在瀏覽器前面並繼續執行頁面重新加載(Cmd-R),可能大約有一半時間CloudFront會正確返回304,另一半時間會錯誤地返回200以及所有內容。在與頁面交互之前等待5分鐘到期,主要產生200個,僅有少數304個。這種奇怪的行爲適用於HTML頁面上引用的所有文件(.css,.js,.png等)以及包含的HTML頁面本身。我知道我的應用程序編碼正確,因爲如上所述,直接點擊ELB而不經過CloudFront會得到預期的304結果。有任何想法嗎?

回答

10

答案是在寫的看似無關的一塊亞馬遜文檔的一個晦澀的句子發現:

When you configure CloudFront to forward cookies to your origin [...] If-Modified-Since and If-None-Match conditional requests are not supported.

奇怪,但確確實實的現實狀況差的很遠;這並不是說,轉發cookie到您的原始服務器禁用條件請求,而是禁用它們有時 - HTTP結果代碼(304 vs 200)幾乎是隨機的。

重要的是要注意,即使您根本不使用cookie,您也會被這種奇怪的行爲所困擾。它仍然是絕對必要的正向餅乾下拉菜單中設置爲「無」,如圖下圖中:

enter image description here

切換到「無」修復了我原來的職位描述的錯誤行爲設置。

雖然這個解決方案給你提出了另一個問題。您要求CloudFront在將請求轉發給您的來源之前完全去除所有Cookie。但是您的原始服務器可能需要這些cookie。此外,如果您使用ELB(負載平衡器)作爲您的來源,ELB依賴維護粘性會話的關鍵cookie將被完全丟棄。不好。

解決cookie剝離問題將取決於您的網站的組織方式。在我的情況下,僅當將AJAX數據發佈到myDomain.com/ajax/時,才需要傳輸cookie(會話相關或其他)。由於所有依賴於Cookie的URL屬於ajax/*類別,因此必須創建該路徑的新行爲規則,並且在該規則中,並且僅在該規則下,將Forward Cookies下拉列表設置爲「All」,而不是「None」 「。

所以它就是這樣。希望這可以幫助某人。

相關問題