2009-08-12 119 views
122

我正在使用Amazon的CloudFront提供我的Web應用程序的靜態文件。強制CloudFront分配/文件更新

有沒有辦法告訴一個cloudfront發行版,它需要刷新它的文件或指出一個應該刷新的單個文件?

亞馬遜建議您使用logo_1.gif,logo_2.gif等文件進行版本化,以解決此問題,但這似乎是一個非常愚蠢的解決方案。是否絕對沒有其他辦法?

+0

的可能重複[我怎樣才能更新在亞馬遜的CDN文件(CloudFront的) ?](http://stackoverflow.com/questions/1086240/how-can-i-update-files-on-amazons-cdn-cloudfront) – 2012-05-21 09:20:47

+0

作爲旁註,我不認爲這是愚蠢的命名靜態文件那。我們一直在使用它,並根據版本控制中的文件版本進行自動重命名,這爲我們節省了很多麻煩。 – eis 2012-05-21 09:23:01

+0

@eis,除非您需要替換的文件已鏈接到1000個不同的在線位置。祝你好運,所有這些鏈接更新。 – 2012-07-31 19:53:21

回答

116

好消息。亞馬遜最終添加了失效功能。 See the API Reference

這是從API參考的示例請求:

POST /2010-08-01/distribution/[distribution ID]/invalidation HTTP/1.0 
Host: cloudfront.amazonaws.com 
Authorization: [AWS authentication string] 
Content-Type: text/xml 

<InvalidationBatch> 
    <Path>/image1.jpg</Path> 
    <Path>/image2.jpg</Path> 
    <Path>/videos/movie.flv</Path> 
    <CallerReference>my-batch</CallerReference> 
</InvalidationBatch> 
+3

Sweeeeeeeeeeeeeet! – Martin 2010-09-06 21:20:08

+9

請注意,失效將需要一些時間(根據我讀過的一些博客文章顯然是5-30分鐘)。 – 2012-03-04 00:54:17

+26

如果您不想自己提出API請求,則還可以登錄Amazon控制檯並在其中創建失效請求: http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html – j0nes 2012-07-26 06:50:45

10

隨着失效API,它在幾分鐘得到更新。
退房PHP Invalidator

+0

這正是我所期待的。在從git中自動部署時,我將在Beanstalkapp的web鉤子中鉤住它!感謝您的鏈接! – cointilt 2011-04-28 18:42:51

9

Bucket Explorer有一個用戶界面,這使得現在很容易。操作方法如下:

右鍵單擊您的存儲桶。選擇「管理分配」。
右鍵點擊你的發行版。選擇「獲取Cloudfront失效列表」 然後選擇「創建」以創建新的失效列表。 選擇要失效的文件,然後點擊「無效」。等待5-15分鐘。

+1

謝謝,超級有用! – 2011-09-13 14:39:03

4

剛剛張貼通知任何人訪問此頁 (上'的Cloudfront文件刷新的第一個結果),有一個易於使用的+接入online invalidator available at swook.net

這個新的無效化是:

  • 完全在線(無需安裝)
  • 全天候(由Google託管)並且不需要任何成員資格。
  • 有歷史支持和路徑檢查,讓您輕鬆使您的文件無效。 (通常在第一次失效後只需點擊幾下!)
  • 這也是非常安全的,正如您在閱讀release post時發現的那樣。

完全披露:我做到了。玩的開心!

+1

對不起,但即使是「你說」沒有存儲或噓的證書......一個人不應該把他的證書給第三方。可能是實施遠程亞馬遜認證或什麼? – 2015-01-09 16:39:00

+0

你應該至少把它放在https後面。 – 2015-10-19 12:50:37

+0

在線工具通常很好,但爲第三方工具提供憑據將是一個有效的安全問題。我會建議使用官方Web控制檯或[官方CLI工具](http://stackoverflow.com/a/34957651/728675)。 – RayLuo 2016-01-22 23:34:20

15

截至3月19日,亞馬遜現在允許Cloudfront的緩存TTL爲0秒,因此您(理論上)不應該看到過時的對象。因此,如果您在S3中擁有資產,則可以簡單地轉到AWS Web Panel => S3 => Edit Properties => Metadata,然後將「Cache-Control」值設置爲「max-age = 0」。

這是直接從API documentation

要控制CloudFront的緩存是否一個對象,並能持續多久,我們建議您使用Cache-Control頭與最大年齡=指令。 CloudFront將對象緩存指定的秒數。(最小值爲0秒。)

+0

新的AWS控制檯UI中的此設置在哪裏?我找不到它。 – 2013-01-18 00:51:44

+0

我找到了單個文件的設置,但是有沒有設置可以使上傳到我的存儲桶的任何內容的TTL爲0? – 2013-01-18 01:01:52

+0

雖然我也肯定對水桶範圍內的設置感興趣,但我發現這是一個更快/更好的解決方案。無效請求(以及API的其餘部分)非常混亂且記錄不完整,並且在立即運行之前我將我的輪子旋轉了3個小時。 – 2014-08-01 15:38:44

4

如果您已經安裝boto(這不只是爲Python,但還安裝了一堆有用的命令行實用程序),它提供了一個命令行UTIL特意叫cfadmin或'雲鋒管理員' 它提供了以下功能:通過運行

Usage: cfadmin [command] 
cmd - Print help message, optionally about a specific function 
help - Print help message, optionally about a specific function 
invalidate - Create a cloudfront invalidation request 
ls - List all distributions and streaming distributions 

您invaliate事情:

$sam# cfadmin invalidate <distribution> <path> 
+0

實際上,cfadmin是一個非常有用的工具,尤其是在需要從控制檯\ bash \ travis ci部署腳本中重置CloudFront緩存時。順便說一句,這裏是[post後如何在Travis部署過程中重置\使CoudFront緩存無效](http://www.mikitamanko.com/blog/2014/10/26/travis-invalidate-aws-cloudfront-cache/) – 2014-10-26 19:59:22

2

在Ruby中,使用霧寶石

AWS_ACCESS_KEY = ENV['AWS_ACCESS_KEY_ID'] 
AWS_SECRET_KEY = ENV['AWS_SECRET_ACCESS_KEY'] 
AWS_DISTRIBUTION_ID = ENV['AWS_DISTRIBUTION_ID'] 

conn = Fog::CDN.new(
    :provider => 'AWS', 
    :aws_access_key_id => AWS_ACCESS_KEY, 
    :aws_secret_access_key => AWS_SECRET_KEY 
) 

images = ['/path/to/image1.jpg', '/path/to/another/image2.jpg'] 

conn.post_invalidation AWS_DISTRIBUTION_ID, images 
甚至失效

,它仍然需要5-10分鐘無效處理並刷新所有亞馬遜邊緣服務器上

+0

你剛剛救了我的命! – 2014-06-10 20:47:03

3

一個非常簡單的方法來做到這一點是文件夾版本。

因此,如果您的靜態文件是數百個例子,只需將它們全部放入由year +版本控制的文件夾中。

比如我使用了一個名爲2014_v1其中裏面我有我的所有靜態文件的文件夾...

所以我的HTML裏面我始終把參考的文件夾。 (當然我有一個PHP包括我已經設置文件夾的名稱。)所以通過更改1文件它實際上改變了我所有的PHP文件..

如果我想要一個完整的刷新,我只需重命名文件夾到2014_v2到我的源代碼和更改php內包括到2014_v2

所有的HTML自動更改並詢問新的路徑,cloudfront MISS緩存並請求它到源。

例如: SOURCE.mydomain.com是我的源碼, cloudfront.mydomain.com是CNAME to cloudfront distribution。

所以PHP叫這個文件 cloudfront.mydomain.com/2014_v1/javascript.js ,當我想要一個完全刷新,只是我的文件夾重命名爲源,以「2014_v2」和我改變PHP包括通過設置該文件夾爲「2014_v2」。

像這樣,沒有延遲無效和沒有成本!

這是我在stackoverflow中的第一篇文章,希望我做得很好!

0

如果您正在使用AWS,您可能也會使用其官方CLI工具(遲早)。 AWS CLI version 1.9.12或以上版本支持使文件名列表無效。

完全披露:我做到了。玩的開心!

7

自動更新設置在5分鐘

OK,夥計們。現在執行自動CloudFront更新(失效)的最佳方法是創建Lambda函數,每次將任何文件上載到S3存儲桶(新存儲或重寫)時都會觸發該函數。

即使你從未使用過lambda函數,它是很容易 - 只需跟着我一步一步的指示,它會帶僅需5分鐘:

步驟1

轉到https://console.aws.amazon.com/lambda/home並單擊創建lambda函數

步驟2

點擊空白函數(自定義)

步驟3

點擊空(撫摩)框中,選擇S3從組合

步驟4

選擇存儲區(與CloudFront分配相同)

步驟5

設置一個事件類型爲 「對象創建(全部)」

步驟6

設置前綴和後綴或保留空白,如果你不不知道它是什麼。

步驟7

檢查啓用觸發複選框,然後單擊下一步

步驟8

名稱的功能(是這樣的:YourBucketNameS3ToCloudFrontOnCreateAll

第9步

選擇Python 2。在一個

from __future__ import print_function 

import boto3 
import time 

def lambda_handler(event, context): 
    for items in event["Records"]: 
     path = "/" + items["s3"]["object"]["key"] 
     print(path) 
     client = boto3.client('cloudfront') 
     invalidation = client.create_invalidation(DistributionId='_YOUR_DISTRIBUTION_ID_', 
      InvalidationBatch={ 
      'Paths': { 
      'Quantity': 1, 
      'Items': [path] 
      }, 
      'CallerReference': str(time.time()) 
      }) 

步驟11

打開https://console.aws.amazon.com/cloudfront/home:7(或更高版本),爲運行時

步驟10

粘貼下面的代碼,而不是默認Python代碼新的瀏覽器選項卡並複製您的CloudFront分配ID以供下一步使用。

步驟12

返回拉姆達標籤和粘貼分配ID而非_YOUR_DISTRIBUTION_ID_在Python代碼。保持周圍的引號。

步驟13

處理:lambda_function.lambda_handler

步驟14

點擊作用組合框並選擇創建自定義角色。瀏覽器中的新選項卡將打開。

步驟15

點擊視圖政策文件,單擊編輯,單擊OK,並替換爲以下角色定義(這是):

{ 
    "Version": "2012-10-17", 
    "Statement": [ 
    { 
     "Effect": "Allow", 
     "Action": [ 
     "logs:CreateLogGroup", 
     "logs:CreateLogStream", 
     "logs:PutLogEvents" 
     ], 
     "Resource": "arn:aws:logs:*:*:*" 
    }, 
    { 
     "Effect": "Allow", 
     "Action": [ 
      "cloudfront:CreateInvalidation" 
     ], 
     "Resource": [ 
      "*" 
     ] 
    } 
    ] 
} 

步驟16

點擊允許。這會讓你回到一個lambda。仔細檢查您剛剛創建的角色名稱是否在現有角色組合框中被選中。

步驟17

存儲器(MB) 128和超時至5秒。

步驟18

點擊接下來,然後單擊創建功能

19步

你是好去!現在,每次您將上傳/重新上傳任何文件到S3,都將在所有CloudFront Edge位置進行評估。

PS - 在測試時,確保您的瀏覽器正在從CloudFront加載映像,而不是從本地緩存加載。

PSS - 請注意,每月只有前1000個文件失效是免費的,每個失效超過限制成本$ 0.005美元。 Lambda功能的額外費用也可能適用,但它非常便宜。

+0

只是每個S3批次的最後一項? – Phil 2017-01-09 03:47:29

+0

@Phil代碼是這樣寫的,所以只有新上傳的文件將被無效,而不是整個桶。在多文件上傳的情況下,每個文件將分別失效。奇蹟般有效。 – Kainax 2017-01-14 04:57:36

+0

此代碼按預期工作的唯一原因是因爲S3每個通知只包含一個項目,即數組的長度總是爲1,因此即使您一次上傳多個文件,也會得到一個全新的每個文件的通知。在任何情況下,您都不會收到整個存儲桶的通知。無論如何,如果AWS改變了這種行爲,那麼這個寫入的代碼還沒有準備好。編寫處理整個陣列的代碼更安全,不管長度如何,這是我的原始(可惜錯過)的一點。 – Phil 2017-01-15 23:32:09

0

當前AWS CLI支持在預覽模式下失效。在控制檯中運行一次:

aws configure set preview.cloudfront true 

我使用npm部署我的web項目。我有以下腳本我package.json

{ 
    "build.prod": "ng build --prod --aot", 
    "aws.deploy": "aws s3 sync dist/ s3://www.mywebsite.com --delete --region us-east-1", 
    "aws.invalidate": "aws cloudfront create-invalidation --distribution-id [MY_DISTRIBUTION_ID] --paths /", 
    "deploy": "npm run build.prod && npm run aws.deploy && npm run aws.invalidate" 
} 

有以上的地方,你可以部署您的網站的腳本:

npm run deploy