[英]AWS Lambda function times out but works on local instance
我正在AWS上编写一个NodeJS应用程序,该应用程序执行以下操作:
该代码在我的本地节点实例上运行良好。 整个过程通常不到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();
}
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
对象上收到一个错误,该错误可以帮助您进一步解决问题。
.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.