AWS Lambda@Edge 502 CloudFront 中的 LambdaValidationError

问题描述 投票:0回答:1

我的架构是这样设置的。

产品的GET请求:id100x100image.jpeg被发送到CloudFront。

CloudFront会把100x100维度的image.jpeg发回给客户端,如果是缓存的,否则会调用Origin,Origin会调用Lambda函数来调整图片的大小。从Lambda函数中得到的调整后的图片将被放到S3 Bucket中,并作为响应发送回来。

我已经删除了ViewerRequest Lambda函数。Architecture of my set up这是我的NodeJS代码。

const AWS = require('aws-sdk');
const S3 = new AWS.S3({
    signatureVersion: 'v4',
});
const Sharp = require('sharp');
const BUCKET = 'xBucket';

exports.handler = (event, context, callback) => {
    let response = event.Records[0].cf.response;

    //check if image is not present
    if (response.status == 404) {
        let request = event.Records[0].cf.request;
        let path = request.uri;
        let key = path.substring(1);
        console.log('key path:', key);

        // parse the prefix, width, height and image name
        // Ex: key=images/200x200/webp/image.jpg
        let prefix, originalKey, match, width, height, requiredFormat, imageName, productId;

        // key=products/12/100x100/image.jpg
        try {
          match = key.match(/(.*)\/(\d+)\/(\d+)x(\d+)\/(.*)/);
          prefix = match[1]; //products
          productId = match[2];
          width = parseInt(match[3], 10); //100
          height = parseInt(match[4], 10);//100

          console.log(`match: ${match} | prefix: ${prefix} | productId: ${productId} | width: ${width} | height: ${height}`);

          // correction for jpg required for 'Sharp'
          requiredFormat = match[5].split('.')[1] === "jpg" ? "jpeg" : match[4].split('.')[1];
          console.log('requiredFormat: ', requiredFormat);
          imageName = match[5];

          originalKey = `${prefix}/${productId}/${imageName}`; // products/12/fjords.jpg
          console.log('Original Key:', originalKey);

          // get the source image file
          S3.getObject({ Bucket: BUCKET, Key: originalKey }).promise()
            .then(data => {
              console.log('data:', data);
              return Sharp(data.Body)
                .resize(width, height)
                .toFormat(requiredFormat)
                .toBuffer()
              })
            .then(buffer => {
              console.log('image resized');
                // save the resized object to S3 bucket with appropriate object key.
                S3.putObject({
                    Body: buffer,
                    Bucket: BUCKET,
                    ContentType: 'image/' + requiredFormat,
                    CacheControl: 'max-age=31536000',
                    Key: key,
                    StorageClass: 'STANDARD'
                }).promise()
                // even if there is exception in saving the object we send back the generated
                // image back to viewer below
                .catch((err) => { console.log(`Exception while writing resized image to bucket: ${err}`)});

                console.log('resized imaged updated');

                // generate a binary response with resized image
                response.status = 200;
                response.body = buffer.toString('base64');
                response.bodyEncoding = 'base64';
                response.headers['content-type'] = [{ key: 'Content-Type', value: 'image/' + requiredFormat }];

                console.log('response event:', event);

                console.log('FINAL RESPONSE: ', response);

                callback(null, response);
              })
            .catch(err => { console.log("Exception while reading source image :%j",err) })
        } catch (e) {
          console.log(e);
        }
    } // end of if block checking response statusCode
    else {
        // allow the response to pass through
        callback(null, response);
    }
};

根据AWS文档,502错误可能是由于Lambda验证错误,OriginResponseLamda返回的响应不符合Lambda@Edge事件结构的结构。https:/docs.aws.amazon.comAmazonCloudFrontlatestDeveloperGuidehttp-502-lambda-validation-error.html。

错误是502 ERROROR该请求无法被满足,Lambda函数返回无效的json。json输出必须是一个对象类型。

不知道为什么在 CloudWatch 中也找不到 Lambda 函数日志...

node.js amazon-web-services amazon-s3 aws-lambda
1个回答
0
投票

如果您仍然没有解决这个问题,那么您可以检查一下。

  • 响应体的最大大小(1MB)。如果较大,最好返回一个 302 到渲染的图像上。

  • 该功能的超时设置(即如果超过30秒)。

资料来源: https:/docs.aws.amazon.comAmazonCloudFrontestDeveloperGuidecloudfront-limits.html#limits-lambda-at-edge。

© www.soinside.com 2019 - 2024. All rights reserved.