如何在长时间执行时忽略AWS Lambda超时限制300秒?

时间:2016-12-19 14:59:36

标签: node.js amazon-web-services amazon-s3 aws-lambda

我在使用Node.js的AWS Lambda中遇到超时问题,默认超时时间为300秒。

我想从S3存储桶下载zip size>300MB,然后解压缩后,将其上传到同一存储桶中的临时文件夹中。

但由于数据繁重,我无法在时间间隔内完成此操作。

我可以使用EBS,但希望得到任何可以使用Lambda函数的最近解决方案。

如果我能得到相关的建议来完成这项任务,那就太棒了。

以下是我在Lambda函数中编写的内容。

exports.handler = (event, context, callback) => {
    console.log('Received event for big file:', JSON.stringify(event, null, 2));

    // Get the object from the event and show its content type
    const bucket = event.Records[0].s3.bucket.name;
    const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    const params = {
        Bucket: bucket,
        Key: key,
    };
    s3.getObject(params, (err, data) => {
        if (err) {
            console.log('Error', err);
            const 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);
            callback(message);
        } else {
            console.log('Started to save buffers....');
            JSZip.loadAsync(data.Body).then(function(zip) {
                console.log('Started to extract files.....');
                async.eachSeries(zip.files, function(item, cbk1) {
                    if (!item.dir) {
                        async.waterfall([function(cbk) {
                            zip.file(item.name).async("text").then(function(content) {
                                cbk(null, content)
                            })
                        }], function(err, content) {
                            s3.putObject({
                                Bucket: bucket,
                                Key: 'bigtemp/' + item.name.replace(/^.*[\\\/]/, ''),
                                Body: content
                            }, function(err, result) {
                                if(result && result.ETag){
                                console.log('uploaded file: ', result.ETag);
                                }
                                console.log('Error ', err);
                                cbk1();
                            });
                        })
                    } else {
                        cbk1();
                    }
                });
            });
            callback(null, data.ContentType);
        }
    });
}; 

2 个答案:

答案 0 :(得分:10)

超时由AWS强制执行,虽然它可能会在未来发生变化(已经发生过两次 - it is 15 minutes as of this writing。之前为300秒,从原始值60秒更新)赢得了#今天帮助你。单独使用Lambda并不适合长时间运行的流程。

选项1:通过在Docker中模拟AWS Lambda迁移到ECS

存在将lambda函数移植到ECS的解决方案,而无需通过在docker容器中模拟lambda来重写函数。您可以使用docker-lambdanode-docker-lambda在docker中模拟lambda,然后只需通过runTask传递事件。

如果您最终改变主意想要维护lambda函数,另一个示例使用lambda作为事件接收器并将大部分工作移动到ECS中。

一些示例实现:

选项2:AWS步骤功能

如果超时在单个特定操作中没有瓶颈,您可以将其拆分为AWS Step Functions,从而有效地将一个lambda转换为多个lambda。因此,一个函数将调用S3 getObject,另一个函数将调用zip,另一个函数调用S3 putObject,依此类推,以便绕过超时。我怀疑情况并非如此,但值得一提。

答案 1 :(得分:2)

这是一个较晚的帖子,但最近限制已增加到15分钟。