我正在努力理解Amazon Lambda。这只是对s3模板进行了轻微修改,以查看上传文件的内容类型。
我收到的事件日志和params日志都显示在cloudwatch中,但就像s3.getObject()永远不会被执行一样,因为数据日志的错误日志都不会显示在日志中,我得到的只是一个超时后超时的任务。
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: 'latest'});
exports.handler = function(event, context) {
console.log('Received event:', JSON.stringify(event, null, 2));
// Get the object from the event and show its content type
var bucket = event.Records[0].s3.bucket.name;
var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/+/g, ' '));
var params = {
Bucket: bucket,
Key: key
};
console.log(params);
s3.getObject(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
/*
if (err) {
var message = "Error getting object " + key + " from bucket " + bucket +
". Make sure they exist and your bucket is in the same region as this function.";
console.log(message);
context.fail(message);
} else {
console.log('CONTENT TYPE:', data.ContentType);
context.succeed(data.ContentType);
}
*/
});
};
以下是当前IM角色,我需要做一些更改吗?
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DetachNetworkInterface",
"ec2:DeleteNetworkInterface"],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetObject",
"s3:PutObject"],
"Resource": "arn:aws:s3:::*"
},
{
"Action": "lambda:*",
"Effect": "Allow",
"Resource": "arn:aws:lambda:*"
}]
}
我以前遇到过这个问题。这种情况发生在验证、构建和签名回调执行之后,但在发送回调发生之前。本质上,其中一个套接字进入僵尸模式。我已经向AWS报告了这一点,但他们还没有做出修复。要"修复",请在实例化s3客户端时设置套接字超时。套接字将超时,操作将自动重试。
var s3 = new AWS.S3({httpOptions: { timeout: 2000 }});
默认情况下,超时时间为两分钟,这就是为什么在超时时间明显更短的Lambda中发生这种情况会有问题。
在ListBucket之前,您需要ListAllBuckets。我建议您限制您的lambda访问权限。
{
"Statement":[
{
"Effect":"Allow",
"Action":[
"s3:ListAllMyBuckets"
],
"Resource":"arn:aws:s3:::*"
},
{
"Effect":"Allow",
"Action":[
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Resource":"arn:aws:s3:::yourBucket"
},
{
"Effect":"Allow",
"Action":[
"s3:GetObject"
],
"Resource":"arn:aws:s3:::yourBucket/*"
}
]
}
您必须在lambda的末尾包含一个显式回调,否则它将在s3回调函数被命中之前自动停止运行。
例如:
module.exports.getS3Object = async (event, context, callback) => {
const AWS = require('aws-sdk');
const S3 = new AWS.S3();
S3.getObject({ Bucket: "exampleBucket", Key: "exampleKey" })
.promise()
.then(data => console.log("finished"))
.catch(err => console.log("there was an error" + err))
callback(null, {statusCode: "200", body:"yay"}); //MUST INCLUDE
}