我有以下配置:
Cloudfront - ELB - AutoScalingGroup - EC2s
- Cloudfront
file-[hash].js
从自定义来源(ELB)提供文件(名称中带有 chunkhash)。 - EC2
file-[hash].js
为 Cloudfront 提供文件以及index.html
指向.js
Cloudfront 上适当文件的动态生成的文件。 - ELB 已启用连接耗尽。
一切正常,直到触发具有更改资产的 Cloudformation 部署(假设从file-1.js
到file-2.js
)——当打开新版本时,浏览器会在一小段时间内获取index.html
指向 的新文件file-2.js
,但当它尝试下载时,file-2.js
Cloudfront 会返回 404,从而向用户显示错误。
我理解这是因为蓝/绿部署的工作方式 - 即,有时应用程序的两个版本同时工作,并且 ELB 可以将一个请求重定向到新版本(来自index.html
浏览器的请求),将第二个请求重定向到旧版本(来自 Cloudfront 的请求file-2.js
)。
Cloudfront 文档说你应该“在所有服务器上托管和提供相同的内容”,但我如何在部署期间实现这一点?是否可以强制在任何给定时间只能通过 ELB 访问单个版本的应用程序,以便 Cloudfront 永远不会为新资产获得 404?
如果没有,除了从自定义来源切换到 S3 之外,还有其他选择可以解决这个问题吗?(由于部署/维护的复杂性,希望避免这种情况)
请注意,从更新策略 AutoScalingRollingUpdate 切换到 AutoScalingReplacingUpdate 没有帮助:
助理秘书长: 类型:AWS::AutoScaling::AutoScalingGroup 创建策略: 资源信号: 数数: 参考文献:2 超时:PT10M 更新政策: 自动缩放替换更新: WillReplace:true
答案1
我认为解决这个问题的方法是将静态.js文件保存在S3中,并在发布新应用程序时将以前的版本与新版本一起维护。
CloudFront 将提供来自 S3 的静态内容和来自 EC2 的动态内容。
先将静态内容发布到 S3,然后开始转换。
在这种情况下,动态生成的索引页将引用旧版本中的一个 S3 存储桶,以及新版本中的另一个存储桶。由于这两个资源始终在 S3 中解析,因此不会出现 404。