【发布时间】:2019-11-19 12:19:57
【问题描述】:
我的 API 上有一个终端节点,它仅使用 AWS 开发工具包为我们的 S3 存储桶之一生成预签名 URL。在本地访问端点时,每次都可以正常工作。但是,在对已部署版本(在 Fargate 上运行)的第一次请求时,第一次调用 总是 返回基本 S3 URL:
https://s3.amazonaws.com/
如果您点击 API 秒 次,它会生成正确的 URL,并且只要 API 是热的,它就会继续这样做。如果您等待足够长的时间并再次尝试击中它,它会再次发生。
我已经验证了生成 URL 的参数是正确的,即使它生成了错误的 URL。我还在同一方法中添加了重试逻辑,但这会继续返回无效的 URL。
这里是有问题的代码(包括重试):
const s3Params = {
Key: fileName,
Expires: 120,
ContentType: contentType,
ACL: "public-read",
Bucket: process.env.IMAGE_UPLOAD_BUCKET,
};
let uploadUrl = this.awsService.getS3Instance().getSignedUrl("putObject", s3Params);
// Sometimes this call fails and returns a blank URL
if (uploadUrl === "https://s3.amazonaws.com/") {
// Try one more time
uploadUrl = this.awsService.getS3Instance().getSignedUrl("putObject", s3Params);
}
return [uploadUrl, s3Params.Key];
对进一步解决此问题有什么建议吗?
【问题讨论】:
-
this.awsService.getS3Instance()返回什么样的对象,又是如何构造的?第一直觉是构造函数可能会从region: 'ex-ample-1'之类的东西中受益,因为它异步发现存储桶区域,但对于第一个请求来说为时已晚。第二个本能是争辩说这只会让它变慢,而不是让它出错。而且...桶在哪里(哪个特定区域),fargate 集群在哪里? -
this.awsService.getS3Instance()只是返回 S3 库的构造实例:private s3 = new AWS.S3({ signatureVersion: "v4", });存储桶发现肯定是它,我会尝试并报告。 -
再看一遍,我刚刚注意到你没有异步调用
getSignedUrl()。出于这个原因,我之前说的可能是不正确的,“这只会让它变慢,而不是让它出错。”我怀疑在后台进行了异步尝试以发现存储桶区域,但它会在对getSignedUrl()的第一次同步调用完成后的某个时间点返回。我怀疑,通过回调或承诺使这个异步也应该解决问题。 -
将存储桶添加到配置中似乎没有做任何事情。我绝对同意这是一个异步问题,所以我会继续探讨它。
标签: node.js amazon-s3 aws-fargate