【问题标题】:Cannot retrieve data on S3 Bucket from a deployed lambda无法从已部署的 lambda 检索 S3 存储桶上的数据
【发布时间】:2020-03-26 01:19:38
【问题描述】:

我从 lambda 函数调用了一个 step 函数,它处理数据并将它们存储在 S3 存储桶中。在这个 lambda 函数中,我尝试下载数据,但收到一条错误消息,显示“AccessDenied”(请参阅​​下文)。

如果我第二次运行这个 lambda 函数,我没有收到任何错误并且执行成功终止。我的理解是,在第一次运行期间,我尝试下载数据时尚未存储数据,这可以解释为什么在我第二次尝试时它运行良好。

我正在使用这对 async/await 认为这足以在等待数据存储时保持执行。是不是我做的不对?

这里是代码的摘录(步骤功能这里不详述):

async function downloadData(){
    var rawData = await s3.getObject({Bucket: 'myBucket/', Key: 'myData.json'}).promise();
    var data = JSON.parse(rawData.Body.toString('utf-8'));
    return data;
}

async function invokeStepFunction(){
    const stepfunctions = new AWS.StepFunctions();
    var params = {
        stateMachineArn: process.env.state_machine_arn,
        input: JSON.stringify({"Bucket": 'myBucket/'})
    };
    await stepfunctions.startExecution(params).promise();
}

const AWS = require('aws-sdk');
AWS.config.update({region: process.env.region});
const s3 = new AWS.S3({apiVersion: '2006-03-01'});

module.exports.handler = async (event, context) => {
    await invokeStepFunction();
    const data = await downloadData();
    console.log(data);
}

这是错误信息:

{"errorType":"AccessDenied","errorMessage":"AccessDenied","code":"AccessDenied","message":"AccessDenied","region":null,"time":"2020-03-25T13:13:20.832Z","requestId":"...","extendedRequestId":"...","statusCode":403,"retryable":false,"retryDelay":91.97041111587372,"stack":["AccessDenied: Access Denied","    at Request.extractError (/var/runtime/node_modules/aws-sdk/lib/services/s3.js:816:35)","    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:106:20)","    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:78:10)","    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)","    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)","    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)","    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10","    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)","    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)","    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"]}

【问题讨论】:

  • 记录 s3 对象可能会帮助您查看第一次执行和以后的执行是否有任何差异。
  • @AmitaMohite 谢谢。我可以在第一次运行的日志中看到,当我尝试下载它们时,数据还没有出现(下载看起来太快了两秒)。对于第二次执行,数据已经存在,因为第一次执行 - 这就是它工作的原因。通过使用时间戳将我的数据命名为上传/下载,没有执行工作:当要求下载时,数据仍然不存在。
  • 我的意思是,记录 s3 对象。在这种情况下,对象变量“s3”。它将具有区域、权限等各种字段。看看你是否发现第一次执行和以后的执行有什么不同。

标签: amazon-web-services amazon-s3 async-await aws-sdk-nodejs


【解决方案1】:

当您等待 step 函数 startExecution 调用时,您正在等待 AWS Step Functions 表明它已收到您开始执行 Step Function 的请求。它确实表明 Step Function 本身已经运行完成。

所以,在 Step Function 实际将数据存储到 S3 之前,您正在执行 downloadData,并且该文件第一次在 S3 中不存在。当您稍后调用它时,downloadData 似乎成功,但几乎可以肯定它正在下载存储在 S3 中的对象以前(从第一次运行开始)。

您需要在下载实际发生后的某个时间执行下载步骤。例如,您可以在上传 Step Function 结束时将下载作为附加步骤。

【讨论】:

  • 谢谢@jarmod。我通过设置超时解决了这个问题,这给了足够的时间在下载之前实际上传数据。
  • 这可以很好地用于小物体。但是,对于大型对象,我不会依赖它,因为它们可能无法及时下载,而且您的 Lambda 睡眠几分钟会不必要地花费您的钱。如果我的回答解释了您遇到的问题,请考虑接受它。
猜你喜欢
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
  • 2021-07-03
  • 1970-01-01
  • 2021-07-08
  • 1970-01-01
  • 2020-07-05
  • 2019-10-26
相关资源
最近更新 更多