强制 CloudFront 分发/文件更新

我正在使用亚马逊的 CloudFront 为我的 web 应用程序提供静态文件。

有没有办法告诉 Cloudfront 发行版它需要刷新它的文件或者指出一个应该刷新的文件?

亚马逊建议您将文件的版本设置为 logo _ 1.gif、 logo _ 2.gif 等等,作为解决这个问题的方法,但这似乎是一个相当愚蠢的解决方案。真的没有别的办法了吗?

94435 次浏览

好消息。亚马逊终于添加了一个失效特性。

这是来自 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>

使用失效 API,几分钟内就可以得到更新。
看看 PHP Invalidator

Bucket Explorer 现在有了一个非常简单的用户界面:

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

只是发布通知任何人访问这个页面(第一个结果在“ Cloudfront 文件刷新”) 在 swook.net 上有一个易于使用的在线无效工具

这个新的失效者是:

  • 完全联机(不安装)
  • 可24x7(由谷歌托管) ,不需要任何成员资格。
  • 有历史记录支持和路径检查,让您轻松地使您的文件失效。(通常在第一次失效后只需要几次点击!)
  • 它也是非常安全的,当你读它的 释放柱时你会发现。

说实话,这是我做的,玩得开心!

截至3月19日,Amazon 现在允许 Cloudfront 的缓存 TTL 为0秒,因此(理论上)您应该永远不会看到过时的对象。因此,如果您的资产在 S3中,您可以简单地转到 AWS Web Panel = > S3 = > Edit Properties = > Metadata,然后将“ Cache-Control”值设置为“ max-age = 0”。

这是来自 API 文档的报道:

为了控制 CloudFront 是否缓存一个对象以及缓存多长时间,我们建议使用 Cache-Control 头和 max-age = 指令。CloudFront 以指定的秒数缓存对象。(最小值为0秒。)

如果你已经安装了 Boto(不仅仅是 python,还安装了一些有用的命令行实用程序) ,它提供了一个命令行,直到专门称为 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

你通过跑步使事情失效:

$sam# cfadmin invalidate <distribution> <path>

在红宝石中,使用雾宝石

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

即使在失效时,在所有 Amazon 边缘服务器上处理和刷新失效仍然需要5-10分钟

一个非常简单的方法是文件夹版本控制。

例如,如果您的静态文件有数百个,那么只需将它们全部放到一个名为 year + version oning 的文件夹中。

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

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

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

所有的 HTML 自动更改和请求新的路径,云端 MISS 缓存和请求它的源。

例如: Source.mydomain.com 是我的线人, Cloudfront.mydomain.com 是 CNAME 到 Cloudfront 的分布。

所以 PHP 调用了这个文件 Cloudfront.mydomain.com/2014_v1/javascript.js 当我想要一个完整的刷新,只是我重命名文件夹到源代码为“2014 _ v2”,我改变 PHP 包括设置文件夹为“2014 _ v2”。

这样就没有失效的延迟和没有成本!

这是我在 stackoverflow 的第一个帖子,希望我做得很好!

如果您正在使用 AWS,那么您可能也在使用它的官方 CLI 工具(迟早)。AWS CLI 版本1.9.12或更高版本支持使文件名列表无效。

说实话,这是我做的,玩得开心!

自动更新设置在5分钟

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

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

第一步

转到 https://console.aws.amazon.com/lambda/home并单击 创建一个 lambda 函数

第二步

点击 空白函数(自定义)

第三步

单击空(抚摸)框并从组合中选择 中三

第四步

选择 水桶(与 CloudFront 发行版相同)

第五步

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

第六步

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

第七步

选中 启动引爆器复选框并单击 下一个

第八步

命名函数(比如: YourBucetNameS3ToCloudFrontOnCreateAll)

第九步

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

第十步

粘贴以下代码而不是默认的 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())
})

第十一步

在新的浏览器选项卡中打开 https://console.aws.amazon.com/cloudfront/home,并复制 CloudFront 分发 ID,以便在下一步中使用。

第12步

返回到 lambda 选项卡,在 Python 代码中粘贴您的发行版 id,而不是 _ YOUR _ DISTRIBUTION _ ID _。

第十三步

设置 联络人: lambda _ function. lambda _ handle

第十四步

单击 角色组合框并选择 创建自定义角色。将打开浏览器中的新选项卡。

第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": [
"*"
]
}
]
}

第十六步

允许。这会让你回到 Lambda。仔细检查刚才创建的角色名是否在 现有角色组合框中选中。

第十七步

内存(MB)设置为128,暂停设置为5秒。

第十八步

单击 下一个,然后单击 创建功能

第十九步

你可以走了!现在,每次将任何文件上传/重新上传到 S3时,都将在所有 CloudFront Edge 位置对其进行计算。

PS-测试时,请确保浏览器正在从 CloudFront 加载图像,而不是从本地缓存加载图像。

PSS-请注意,每月只有前1000个文件无效是免费的,每个无效超过限制的费用为0.005美元。此外,Lambda 函数的附加费用可能适用,但它是非常便宜的。

当前的 AWS CLI 支持预览模式下的无效:

aws configure set preview.cloudfront true

我使用 npm 部署我的 Web 项目:

{
"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

去云端。

点击您的 ID/分布。

点击失效。

单击创建无效。

在巨大的示例框中键入 * 并单击“无效”

成交

enter image description here