我正在使用 Amazon 的 CloudFront 来提供我的 Web 应用程序的静态文件。
有没有办法告诉云端分发它需要刷新它的文件或指出应该刷新的单个文件?
亚马逊建议您对您的文件进行版本控制,例如 logo_1.gif、logo_2.gif 等,作为解决此问题的方法,但这似乎是一个非常愚蠢的解决方案。是绝对没有别的办法了吗?
我正在使用 Amazon 的 CloudFront 来提供我的 Web 应用程序的静态文件。
有没有办法告诉云端分发它需要刷新它的文件或指出应该刷新的单个文件?
亚马逊建议您对您的文件进行版本控制,例如 logo_1.gif、logo_2.gif 等,作为解决此问题的方法,但这似乎是一个非常愚蠢的解决方案。是绝对没有别的办法了吗?
好消息。亚马逊终于添加了一个失效功能。请参阅 API 参考。
这是来自 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 月 19 日,亚马逊现在允许 Cloudfront 的缓存 TTL 为 0 秒,因此您(理论上)应该永远不会看到过时的对象。因此,如果您的资产在 S3 中,您可以简单地转到 AWS Web 面板 => S3 => 编辑属性 => 元数据,然后将“Cache-Control”值设置为“max-age=0”。
这直接来自API 文档:
要控制 CloudFront 是否缓存对象以及缓存多长时间,我们建议您将 Cache-Control 标头与 max-age= 指令一起使用。CloudFront 将对象缓存指定的秒数。(最小值为 0 秒。)
使用 Invalidation API,它确实会在几分钟内更新。
查看PHP Invalidator。
5 分钟内自动更新设置
好,朋友们。目前执行自动 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.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 步
单击view policy document,单击edit,单击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
点击Next,然后点击Create function
步骤 19
你已准备好出发!现在,每次您将任何文件上传/重新上传到 S3 时,都会在所有 CloudFront 边缘位置对其进行评估。
PS - 当您进行测试时,请确保您的浏览器正在从 CloudFront 加载图像,而不是从本地缓存中加载。
PSS - 请注意,每月只有前 1000 个文件失效是免费的,每个超出限制的失效成本为 0.005 美元。Lambda 函数也可能会收取额外费用,但它非常便宜。
Bucket Explorer有一个 UI,现在让这变得非常容易。就是这样:
右键单击您的存储桶。选择“管理分发”。
右键单击您的发行版。选择“获取 Cloudfront 失效列表”,然后选择“创建”以创建新的失效列表。选择要失效的文件,然后单击“失效”。等待 5-15 分钟。
如果您安装了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
即使失效,在所有亚马逊边缘服务器上处理和刷新失效仍然需要 5-10 分钟
一种非常简单的方法是 FOLDER 版本控制。
因此,例如,如果您的静态文件有数百个,只需将它们全部放入名为 year+versioning 的文件夹中。
例如,我使用一个名为 2014_v1 的文件夹,里面有我所有的静态文件......
所以在我的 HTML 中,我总是将引用放在文件夹中。(当然我有一个 PHP 包含,我在其中设置了文件夹的名称。)因此,通过更改 1 个文件,它实际上更改了我所有的 PHP 文件..
如果我想要完全刷新,我只需将文件夹重命名为 2014_v2 到我的源代码中,然后将 php 包含更改为 2014_v2
所有 HTML 自动更改并询问新路径,云端 MISS 缓存并将其请求到源。
示例:SOURCE.mydomain.com 是我的来源,cloudfront.mydomain.com 是 CNAME 到 cloudfront 分发。
因此,PHP 将此文件称为 cloudfront.mydomain.com/2014_v1/javascript.js,当我想要完全刷新时,只需将文件夹重命名为“2014_v2”,然后通过将文件夹设置为“2014_v2”来更改 PHP 包含.
像这样没有延迟失效并且没有成本!
这是我在stackoverflow的第一篇文章,希望我做得好!
当前 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
如果您使用 AWS,您可能还会使用其官方 CLI 工具(迟早)。AWS CLI 版本 1.9.12或更高版本支持使文件名列表无效。
完全披露:我做了这个。玩得开心!