强制CloudFront分发/文件更新

时间:2009-08-12 19:17:46

标签: amazon-web-services cloud cdn amazon-cloudfront

我正在使用亚马逊的CloudFront来提供我的网络应用的静态文件。

是否无法告知云端分发需要刷新文件或指出应刷新的单个文件?

亚马逊建议您将文件版本如logo_1.gif,logo_2.gif等作为解决此问题的解决方法,但这似乎是一个非常愚蠢的解决方案。绝对没有别的办法吗?

13 个答案:

答案 0 :(得分:127)

好消息。亚马逊最终添加了一个失效功能。 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>

答案 1 :(得分:19)

截至3月19日,亚马逊现在允许Cloudfront的缓存TTL为0秒,因此您(理论上)永远不应该看到过时的对象。因此,如果您在S3中拥有资产,则只需转到AWS Web Panel =&gt; S3 =&gt;编辑属性=&gt;元数据,然后设置你的&#34; Cache-Control&#34;值为&#34; max-age = 0&#34;。

直接来自API documentation

  

要控制CloudFront是否缓存对象以及持续多长时间,我们建议您使用带有max-age =指令的Cache-Control标头。 CloudFront将对象缓存指定的秒数。 (最小值为0秒。)

答案 2 :(得分:10)

使用Invalidation API,它会在几分钟内更新 查看PHP Invalidator

答案 3 :(得分:10)

5分钟内自动更新设置

好的,伙计们。现在执行自动CloudFront更新(失效)的最佳方法是创建Lambda函数,每次将任何文件上载到S3存储桶(新存储或重写)时都会触发该函数。

即使您之前从未使用过lambda函数,也非常简单 - 只需按照我的分步说明操作即可,只需5分钟:

第1步

转到https://console.aws.amazon.com/lambda/home,然后点击创建lambda函数

第2步

点击空白功能(自定义)

第3步

点击空(抚摸)框并从组合中选择 S3

第4步

选择 Bucket (与CloudFront分配相同)

第5步

事件类型设置为“对象已创建(全部)”

第6步

设置前缀和后缀,如果您不知道它是什么,请将其留空。

第7步

选中启用触发器复选框,然后点击下一步

第8步

为您的功能命名(例如: YourBucketNameS3ToCloudFrontOnCreateAll

第9步

选择 Python 2.7 (或更高版本)为运行时

第10步

粘贴以下代码而不是默认的python代码:

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并复制您的CloudFront分配ID,以便在下一步中使用。

第12步

返回lambda选项卡并在Python代码中粘贴您的分发ID而不是_YOUR_DISTRIBUTION_ID_。保留周围的报价。

第13步

设置处理程序:lambda_function.lambda_handler

第14步

点击角色组合框,然后选择创建自定义角色。浏览器中的新选项卡将被打开。

第15步

点击查看政策文档,点击修改,点击确定,然后用以下内容替换角色定义:

{
  "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功能的额外费用可能适用,但它非常便宜。

答案 4 :(得分:9)

Bucket Explorer有一个用户界面,现在非常简单。方法如下:

右键单击您的水桶。选择“管理分配” 右键单击您的发行版。选择“获取Cloudfront无效列表” 然后选择“创建”以创建新的失效列表。 选择要使其无效的文件,然后单击“无效”。等5-15分钟。

答案 5 :(得分:4)

如果您安装了boto(这不仅适用于python,而且还安装了许多有用的命令行实用程序),它提供了一个专门命名为cfadmin或'cloud front admin'的命令行工具'它提供以下功能:

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

您可以通过以下方式使事情失效:

$sam# cfadmin invalidate <distribution> <path>

答案 6 :(得分:3)

只是张贴以通知访问此页面的任何人(“Cloudfront文件刷新”的第一个结果) 有一个易于使用+访问online invalidator available at swook.net

这个新的无效者是:

  • 完全在线(无安装)
  • 全天候(由Google托管),不需要任何会员资格。
  • 有历史记录支持和路径检查,可以让您轻松地使文件无效。 (通常在第一次失效后只需点击几下!)
  • 它也非常安全,因为您在阅读release post时会发现。

完全披露:我做了这个。玩得开心!

答案 7 :(得分:3)

一种非常简单的方法是使用FOLDER版本。

因此,如果你的静态文件是数百个,只需将它们全部放入一个名为year + versioning的文件夹中。

例如我使用一个名为2014_v1的文件夹,其中我拥有所有静态文件......

所以在我的HTML中我总是把引用放到文件夹中。 (当然我有一个PHP包括我已经设置文件夹的名称。)因此,通过更改1文件它实际上改变了我的所有PHP文件..

如果我想要一个完整的刷新,我只需将文件夹重命名为2014_v2到我的源代码并在php include里面改为2014_v2

所有HTML都会自动更改并询问新路径,Cloudfront MISS缓存并将其请求到源。

实施例: SOURCE.mydomain.com是我的来源, cloudfront.mydomain.com是CNAME到云端分发。

所以PHP调用了这个文件 cloudfront.mydomain.com/2014_v1/javascript.js 当我想要完全刷新时,只需将文件夹重命名为源文件“2014_v2”,然后通过将文件夹设置为“2014_v2”来更改PHP包含。

像这样,没有延迟失效和没有成本!

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

答案 8 :(得分:2)

答案 9 :(得分:2)

在红宝石中,使用雾宝石

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分钟才能在所有亚马逊边缘服务器上处理和刷新失效

答案 10 :(得分:2)

当前的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

答案 11 :(得分:1)

如果您使用的是AWS,您可能还会使用其官方CLI工具(迟早)。 AWS CLI version 1.9.12或更高版本支持使文件名列表无效。

完全披露:我做了这个。玩得开心!

答案 12 :(得分:0)

转到CloudFront。

单击您的ID /分布。

单击无效。

点击创建无效。

在巨型示例框中,键入*,然后单击无效

完成

enter image description here