我正在使用Amazon的CloudFront来提供Web应用程序的静态文件。
有没有办法告诉Cloudfront发行版它需要刷新其文件或指出应刷新的单个文件?
亚马逊建议您对诸如logo_1.gif,logo_2.gif之类的文件进行版本控制,以解决此问题,但这似乎是一个非常愚蠢的解决方案。绝对没有其他方法吗?
我正在使用Amazon的CloudFront来提供Web应用程序的静态文件。
有没有办法告诉Cloudfront发行版它需要刷新其文件或指出应刷新的单个文件?
亚马逊建议您对诸如logo_1.gif,logo_2.gif之类的文件进行版本控制,以解决此问题,但这似乎是一个非常愚蠢的解决方案。绝对没有其他方法吗?
Answers:
好消息。亚马逊终于添加了无效功能。请参阅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>
createInvalidation
请求后,我仍然看到更新需要5到10分钟左右的时间才能使更新无效。请注意,我在您发表4年后写此评论。
自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秒。)
使用Invalidation API,它会在几分钟内得到更新。
查看PHP Invalidator。
5分钟内自动完成更新设置
好,朋友们。现在执行自动CloudFront更新(失效)的最佳可能方法是创建Lambda函数,该函数将在每次将任何文件上传到S3存储桶(新文件或重写文件)时触发。
即使您以前从未使用过lambda函数,也确实很容易-只需按照我的分步说明进行操作,仅需5分钟:
第1步
转到https://console.aws.amazon.com/lambda/home,然后单击“ 创建lambda函数”
第2步
单击空白功能(自定义)
第三步
单击空(描边)框,然后从组合中选择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
单击查看策略文档,单击“ 编辑”,单击“ 确定”,然后将角色定义替换为以下内容(原样):
{
"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函数的额外费用,但它非常便宜。
Bucket Explorer具有一个UI,使现在变得非常容易。这是如何做:
右键单击您的存储桶。选择“管理发行版”。
右键单击您的分布。选择“获取Cloudfront失效列表”,然后选择“创建”以创建新的失效列表。选择要失效的文件,然后单击“失效”。等待5至15分钟。
如果您安装了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>
只需发布信息即可通知访问此页面的任何人(“ Cloudfront File Refresh”的第一个结果)在swook.net上有一个易于使用且易于访问的在线无效器
这个新的无效器是:
全面披露:我做到了。玩得开心!
一种非常简单的方法是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到cloudfront的分发。
因此,PHP将此文件称为cloudfront.mydomain.com/2014_v1/javascript.js,当我想要完全刷新时,只需将文件夹重命名为“ 2014_v2”,然后通过将文件夹设置为“ 2014_v2”来更改PHP include。 。
像这样没有无效的延迟,没有成本!
这是我在stackoverflow中的第一篇文章,希望我做得很好!
在红宝石中,使用雾宝石
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分钟来处理和刷新
当前的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
--paths /
为--paths /*
。我的也像你一样,并且没有使发行无效……
如果您使用的是AWS,则可能还会使用其官方CLI工具(较早或以后)。AWS CLI 1.9.12或更高版本支持使文件名列表无效。
全面披露:我做到了。玩得开心!