AWS Lambda Node函数偶尔会超时

时间:2017-10-04 13:22:44

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

我有一个用Node编写的AWS Lambda函数,可以在将新图像上传到我的S3存储桶时调整图像大小。该功能99%的时间完美无缺。这是我想知道的1%......

在随机的情况下,函数执行超时30秒(这是我们为运行的函数设置的超时)。我不认为增加这个超时会在这里拯救我们任何东西,因为它只是悬而未决。

以下是CloudWatch的日志。蓝线上方是失败,1.5分钟后(蓝线下方)是重试并成功的时间。

CloudWatch logs

这是在将图像上传到S3时在函数中运行的代码。

var async = require('async');
var AWS = require('aws-sdk');
var gm = require('gm').subClass({ imageMagick: true }); // Enable ImageMagick integration.
var util = require('util');
var path = require('path');

var MAX_WIDTH = 345;
var MAX_HEIGHT = 345;

// get reference to S3 client
var s3 = new AWS.S3();

exports.handler = function(event, context, callback) {
    // Read options from the event.
    console.log(
        'Reading options from event:\n',
        util.inspect(event, { depth: 5 })
    );
    var srcBucket = event.Records[0].s3.bucket.name;
    // Object key may have spaces or unicode non-ASCII characters.
    var srcKey = decodeURIComponent(
        event.Records[0].s3.object.key.replace(/\+/g, ' ')
    );
    var dstBucket = process.env.S3_BUCKET;
    var dstKey = event.Records[0].s3.object.versionId + path.extname(srcKey);
    console.log('Image version: ', dstKey);

    // Sanity check: validate that source and destination are different buckets.
    if (srcBucket == dstBucket) {
        callback('Source and destination buckets are the same.');
        return;
    }

    // Infer the image type.
    var typeMatch = srcKey.match(/\.([^.]*)$/);
    if (!typeMatch) {
        callback('Could not determine the image type.');
        return;
    }
    var imageType = typeMatch[1];
    if (imageType != 'jpg' && imageType != 'png') {
        callback('Unsupported image type: ${imageType}');
        return;
    }

    // Download the image from S3, transform, and upload to a different S3 bucket.
    async.waterfall(
        [
            function download(next) {
                // Download the image from S3 into a buffer.
                s3.getObject(
                    {
                        Bucket: srcBucket,
                        Key: srcKey,
                    },
                    next
                );
            },
            function transform(response, next) {
                gm(response.Body).size(function(err, size) {
                    // Infer the scaling factor to avoid stretching the image unnaturally.
                    var scalingFactor = Math.min(
                        MAX_WIDTH / size.width,
                        MAX_HEIGHT / size.height
                    );
                    var width = scalingFactor * size.width;
                    var height = scalingFactor * size.height;

                    // Transform the image buffer in memory.
                    this.resize(width, height).toBuffer(imageType, function(
                        err,
                        buffer
                    ) {
                        if (err) {
                            next(err);
                        } else {
                            next(null, response.ContentType, buffer);
                        }
                    });
                });
            },
            function upload(contentType, data, next) {
                // Stream the transformed image to a different S3 bucket.
                s3.putObject(
                    {
                        Bucket: dstBucket,
                        Key: dstKey,
                        Body: data,
                        ContentType: contentType,
                    },
                    next
                );
            },
        ],
        function(err) {
            if (err) {
                console.error(
                    'Unable to resize ' +
                        srcBucket +
                        '/' +
                        srcKey +
                        ' and upload to ' +
                        dstBucket +
                        '/' +
                        dstKey +
                        ' due to an error: ' +
                        err
                );
                callback(err);
            } else {
                console.log(
                    'Successfully resized ' +
                        srcBucket +
                        '/' +
                        srcKey +
                        ' and uploaded to ' +
                        dstBucket +
                        '/' +
                        dstKey
                );
                callback(null, 'Success');
            }
        }
    );
};

是否有任何设置或方法可以避免这些随机超时?这是一个“启动”问题,前一次运行此函数的时间是5小时,所以在再次执行之前它处于空闲状态?

0 个答案:

没有答案