【问题标题】:s3.getObject().promise() never returns anythings3.getObject().promise() 从不返回任何东西
【发布时间】:2019-08-09 05:21:20
【问题描述】:

如果在符合我在 stackoverflow 和 AWS 开发工具包文档中阅读的所有内容的 Lambda 中使用此代码。

但是,它既不返回任何内容,也不引发错误。代码只是停留在 s3.getObject(params).promise() 上,因此 lambda 函数会在超时时运行,即使超过 30 秒也是如此。我尝试获取的文件实际上是 25kb。

知道为什么会这样吗?

var AWS = require('aws-sdk');
var s3 = new AWS.S3({httpOptions: {timeout: 3000}});    

async function getObject(bucket, objectKey) {
        try {
            const params = {
                Bucket: bucket,
                Key: objectKey
            }
            console.log("Trying to fetch " + objectKey + " from bucket " + bucket)
            const data = await s3.getObject(params).promise()
            console.log("Done loading image from S3")
            return data.Body.toString('utf-8')
        } catch (e) {
            console.log("error loading from S3")
            throw new Error(`Could not retrieve file from S3: ${e.message}`)
        }
    }

在测试函数时,我收到以下超时。

START RequestId:97782eac-019b-4d46-9e1e-3dc36ad87124 版本:$LATEST 2019-03-19T07:51:30.225Z 97782eac-019b-4d46-9e1e-3dc36ad87124 试图从存储桶 zarges-pimdata-test 获取 public-images/low/ZARGES_41137_PROD_TECH_ST_LI.jpg 2019-03-19T07:51:54.979Z 97782eac-019b-4d46-9e1e-3dc36ad87124 从 S3 加载错误 2019-03-19T07:51:54.981Z 97782eac-019b-4d46-9e1e-3dc36ad87124 {"errorMessage":"无法从 S3 检索文件:连接在 3000 毫秒后超时","errorType":"Error","stackTrace" :["getObject (/var/task/index.js:430:15)","","process._tickDomainCallback (internal/process/next_tick.js:228:7)"]} 结束请求 ID:97782eac-019b-4d46-9e1e-3dc36ad87124 报告请求 ID:97782eac-019b-4d46-9e1e-3dc36ad87124 持续时间:24876.90 毫秒 计费持续时间:24900 毫秒内存大小:512 MB 使用的最大内存:120 MB

我正在获取的图像实际上是公开的: https://s3.eu-central-1.amazonaws.com/zarges-pimdata-test/public-images/low/ZARGES_41137_PROD_TECH_ST_LI.jpg

【问题讨论】:

  • 我更新了上面的代码。在使代码对stackoverflow更具可读性时,我犯了一个复制/粘贴错误。以上代码的行为与描述的完全一样。

标签: node.js amazon-web-services amazon-s3 promise


【解决方案1】:
const data = (await (s3.getObject(params).promise())).Body.toString('utf-8')

【讨论】:

  • 每个人都应该知道,经过几个小时的尝试解决这个问题,这个解决方案对我来说是有效的。非常感谢。
【解决方案2】:

这个问题肯定和连接有关。

检查您的 VPC 设置,因为它可能会阻止 Lambda 连接到 Internet(AWS 托管服务作为 S3 只能通过 Internet 访问)。

【讨论】:

  • 其实代码和你建议的一样。我在使代码对 stackoverflow 更具可读性时出现了复制/粘贴错误。我的错-对不起。但是,您建议的代码也不会返回任何内容。我在上面的描述中修复了它。
  • 代码正确。问题可能出在其他地方。也许有联系。您的 Lambda 在 VPN 中吗?您是否仅针对 S3 获得此行为?你能做一个简单的 HTTP 调用吗?
  • 没有VPN,有VPC和VPC安全组。但如果是连接或权限相关的,不应该抛出错误什么的吗?
  • 这取决于连接,假设客户端设置连接超时 5 分钟,你的 lambda 在 3 分钟内死亡,然后你不会收到错误或响应。
  • 你是对的。我没有这个想法。我将代码更改为使用 3000 毫秒的超时。如here 所述,由于重试,我仍然没有收到超时。我需要将 lamda 超时延长到大约一分钟才能收到实际的 S3 超时。
【解决方案3】:

如果您的 Lambda 函数与 VPC 关联,它将失去访问 S3 所需的 Internet 访问权限。但是,您可以在 VPC > Endpoints 设置中创建一个 S3 终端节点,而不是遵循“关联 NAT”等 Lambda 警告,您的 Lambda 函数将按预期工作,无需手动设置您的 Internet 访问VPC。

https://aws.amazon.com/blogs/aws/new-vpc-endpoint-for-amazon-s3/

【讨论】:

    【解决方案4】:

    AWS SDK 的默认超时时间为 120000 毫秒。如果您的 lambda 超时时间更短,那么您将永远不会收到实际错误。

    延长您的 AWS 超时时间

    var AWS = require('aws-sdk');
    var s3 = new AWS.S3({httpOptions: {timeout: 3000}});
    

    或延长 lambda 的超时时间。

    【讨论】:

      【解决方案5】:

      如果您使用的是 localstack,请确保 SSL 为 false 且 s3ForcePathStyle 为 true。

      这是我的问题

      AWS.S3({endpoint: '0.0.0.0:4572', sslEnabled: false, s3ForcePathStyle:true})
      

      更多详情here

      【讨论】:

        【解决方案6】:

        您确定要提供您的 accessKeyId 和 secretAccessKey 吗?在我将它们添加到配置之前,我遇到了超时没有错误消息

        AWS.config.update({ signatureVersion: 'v4', region: "us-east-1", 
                                  accessKeyId: secret.accessKeyID, 
                                  secretAccessKey: secret.secretAccessKey });
        

        【讨论】:

        • 当 lambda 在 AWS 上运行时,它们始终拥有正确的凭据
        猜你喜欢
        • 2011-08-06
        • 1970-01-01
        • 2013-07-14
        • 2023-03-28
        • 2011-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多