繁体   English   中英

AWS Lambda函数超时,但可在本地实例上使用

[英]AWS Lambda function times out but works on local instance

我正在AWS上编写一个NodeJS应用程序,该应用程序执行以下操作:

  • 从远程URL读取XML
  • 解析数据并将其作为JSON存储在DynamoDB上
  • 将8张图片上传到s3存储桶

该代码在我的本地节点实例上运行良好。 整个过程通常不到3秒即可完成。 我可以通过检查AWS s3存储桶和DynamoDB来确认这一点。

但是,当我将其打包为由Lambda运行时,即使超时设置为5分钟,该操作也会过期,并且内存已满。 在检查日志时,我注意到在Lambda上运行时,来自axios的承诺从未返回。 有人可以发现我的代码有任何问题吗? 谢谢。

仅供参考,我是Lambda开发的新手。 我将代码部署到Lambda的方法是,将封闭的export.handler方法添加到本地代码中,并使用模块和package.json将其压缩。 我当然可以使用一些指导来简化此过程。 我提到这一点是因为我不确定这是否与问题有关。

谢谢。

exports.handler = function(event, context, callback) {
async function main() {
    await getData();
    updateDB();
    updateAssets();
}

let dataStore = {};

let s3Assets = [
    'photo1',
    'photo2',
    'photo3',
    'photo4',
    'photo5',
    'logoLarge',
    'logoSmall',
    'logoCompany'
];
let s3Status = {};

s3Assets.map( (i) => {
    // Initialize the status of all assets with 0 (false)
    s3Status[i] = 0;
})

let s3Ready = () => {
    let count = 0;
    s3Assets.map( (i) => {
        count += s3Status[i];    
    })
    console.log(s3Status);
    console.log(`Upload Count: ${count}`);
    if (count === s3Assets.length) {
        console.log(`[SUCCESS] All assets are updated`);
        console.log('< END: updateAssets');
    }
}

let getData = () => {
    ... // code omitted
}

let handleAsset = (asset) => {
    let src = dataStore[asset];
    let destination = dataStore.prefix + asset + '.jpg';

    axios({
        method:'get',
        url: src,
        responseType:'stream'
    }).then( (response) => {
        let body = response.data.pipe(zlib.createGzip());
        let fileType = 'multipart/form-data';

        let s3Promise = s3.upload({
            Bucket: 'someBucket',
            Key: destination,
            Body: body,
            ContentType: fileType,
            ContentEncoding: 'gzip'
        }).promise();

        s3Promise.then( (data) => {
            s3Status[asset] = 1;
            console.log('\n');
            console.log(`[SUCCESS] s3 Upload: ${data.Location}`);
        }).then( () => {
            s3Ready();
        }).catch( (error) => {
            console.log(`[ERROR] s3 Upload: ${error}`);
        });
    }).catch( (error) => {
        console.log(`[ERROR] axios: ${error}`);
    });
}

let updateAssets = () => {
    console.log('> START: updateAssets');
    s3Assets.map( (i) => {
        handleAsset(i)
    });
}

let updateDB = () => {
    ... // code omitted
}

main(); 

}

  1. 我的猜测是,由于您说该程序在本地运行良好,所以您错误地配置了与Lambda关联安全组 确保您具有所有出站端口,并且正确的入站端口已打开。 要确认这是问题所在,或者至少获得更多有针对性的反馈,请尝试向axios请求添加更详细的日志记录。 这是axios文档中的一个非常详细的示例...


}).catch( (error) => {
    console.log(`[ERROR] axios: ${error}`);
    if (error.response) {
        // The request was made and the server responded with a status code
        // that falls out of the range of 2xx
        console.log('error.response.data'error.response.data);
        console.log('error.response.status',error.response.status);
        console.log('error.response.headers',error.response.headers);
    } else if (error.request) {
        // The request was made but no response was received
        // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
        // http.ClientRequest in node.js
        console.log('Error request:',error.request);
    } else {
        // Something happened in setting up the request that triggered an Error
        console.log('Error message', error.message);
    }
    console.log(error.config);
});

您应该在error.request对象上收到一个错误,该错误可以帮助您进一步解决问题。

  1. 造成问题的可能性要小得多,但是值得一提的是.then()链接到s3Promise .then()方法将异步执行,因此s3Status[asset] = 1不一定会在s3Ready();之前完成s3Ready(); 达到条件if (count === s3Assets.length)因此您可以在此处拥有竞争条件。 这几乎是不可能的,但是无论如何我都会纠正,因为它将来可能会引入错误。 运行此示例以了解我的意思...


var test = ()=>new Promise(resolve=> resolve());

test()
  .then(()=> { setTimeout(()=>{console.log('one')},3000)})
  .then(()=>{console.log('two')})

此分配s3Status[asset] = 1是同步的,因此您应该尝试将s3Ready()移到同一s3Ready() .then()块中。

s3Promise.then( (data) => {
    s3Status[asset] = 1;
    console.log('\n');
    console.log(`[SUCCESS] s3 Upload: ${data.Location}`);
    s3Ready();
}).catch( (error) => {
    console.log(`[ERROR] s3 Upload: ${error}`);
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM