2015-04-29 58 views
3

我們目前使用Capifony和ec2-capify插件來將我們的代碼部署到ELB背後的一組實例。我們還使用CloudFront管理靜態資產,我們使用查詢字符串(例如?v1或?v2)進行版本管理。如何在進行滾動部署時確保Cloudfront具有正確的資產版本?

我們偶然發現了一個關於更新資產版本的罕見問題。如果當前版本爲V1,和我們做一次V2一臺服務器的滾動部署,然後會出現以下情況有關V2請求框中:

  1. CloudFront的是問v2和失誤。
  2. CloudFront前往ELB並要求提供資產。
  3. ELB選擇一個服務器,併發生以下兩件事之一:Cloudfront碰到新部署的服務器之一(服務v2),或者碰到舊服務器(v1)。
  4. 無論採用哪種方式,Cloudfront都會將內容存儲爲v2。在遇到v1服務器的情況下,內容不正確。

我們當前的解決方案是我們必須用新的資產版本進行另一次部署。

有沒有辦法迫使Cloudfront通過ELB只命中我們更新的(v2)服務器之一,並忽略v1的?

或者我錯過了一個可以解決問題的備用解決方案嗎?

+0

你有沒有找到一個好的方法嗎? –

+0

有類似的問題,但由於資產版本在名稱中,因此當使用僅有v1的舊服務器時,客戶端將獲得404。 – giorgiosironi

回答

0

我們選擇的辦法是廣泛地放棄我們現有的資產配置(這是希望小!)管道。在「舊」方式中,我們選擇了asset.css?v=<version>模型,其中CloudFront指向由多個實例提供服務的來源。

我們解決這個問題的方法是轉移到哈希名稱資產模型和基於S3的原點。這意味着我們有asset-<hash-of-contents>.css而不是asset.css?v=<version>,它們被同步到S3存儲桶。這個桶逐漸增加了更新和更新的版本,但如果我們決定返回或者像電子郵件這樣的東西鏈接到它(圖像的常見問題),則舊版本始終可用。

在我們部署到包含引用資產的HTML的Web服務器之前,同步到S3腳本運行,因此CloudFront始終能夠提供最新資產。

下面是一個示例腳本:

#!/usr/bin/env bash 

set -e # Fail on any error 
set -x 

if [ "$#" -ne "1" ] 
then 
    echo "Usage: call with the name of the environment you're deploying to" 
    exit 1 
fi 

CDN_ENVIRONMENT=$1 

S3_BUCKET="s3://static-bucket-name-of-your-choice/${CDN_ENVIRONMENT}/" 

echo "Generating assets 

... do the asset generation here ... 

echo "Copying to S3" 

# Now do the actual copying of the web dir. We use size-only because otherwise all files are newer, and all get copied. 
aws s3 sync --exclude "some-folder-to-exclude/*" --acl public-read --size-only ./web/ ${S3_BUCKET} 

echo "Copy to S3 complete" 
0

當的Cloudfront得到了404從你的起源(大概是因爲它尚未收到新的構建),它緩存了404分鐘5分鐘。您可以通過爲您的發行版創建新的「自定義錯誤響應」來更改該行爲。自定義響應允許您設置非常低的TTL,以便Cloudfront將傳遞到您的ELB,直到找到新文件。這個缺點是的Cloudfront將有效不再緩存404 - 您的ELB將需要處理的是負載

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/HTTPStatusCodes.html#HTTPStatusCodes-no-custom-error-pages

相關問題