s3.getObject()。promise()从不返回任何内容

时间:2019-03-18 18:48:42

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

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

但是,它既不返回任何内容也不引发错误。代码只是停留在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尝试从存储桶扎数-pimdata-test中获取public-images / low / ZARGES_41137_PROD_TECH_ST_LI.jpg   从S3加载2019-03-19T07:51:54.979Z 97782eac-019b-4d46-9e1e-3dc36ad87124错误   2019-03-19T07:51:54.981Z 97782eac-019b-4d46-9e1e-3dc36ad87124 {“ errorMessage”:“无法从S3检索文件:连接在3000ms后超时”,“ errorType”:“错误”,“ stackTrace” :[“ getObject(/var/task/index.js:430:15)","","process._tickDomainCallback(internal / process / next_tick.js:228:7)”]}   END RequestId:97782eac-019b-4d46-9e1e-3dc36ad87124   REPORT RequestId:97782eac-019b-4d46-9e1e-3dc36ad87124持续时间:24876.90 ms   计费时间:24900 ms内存大小:512 MB使用的最大内存:120 MB

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

6 个答案:

答案 0 :(得分:1)

AWS开发工具包的默认超时为120000毫秒。如果lambda的超时时间短,那您将永远不会收到实际的错误。

延长您的AWS超时

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

或延长lambda的时间。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

此问题肯定与连接有关。

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

答案 3 :(得分:0)

如果您不想像@tuulka建议的那样在访问主体之前将其提取到变量中,只需将其包装在括号中即可。

const data = (await (s3.getObject(params).promise())).Body.toString('utf-8')

答案 4 :(得分:0)

如果您正在使用localstack,请确保SSL为false,并且s3ForcePathStyle为true。

那是我的问题

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

更多详细信息here

答案 5 :(得分:0)

您确定要提供 accessKeyId 和 secretAccessKey 吗?我有超时没有错误消息,直到我将它们添加到配置中:

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