如何解决在 AWS Lambda 中读取事件流时出现问题 Nodejs 代码根据需要在本地工作,但不在 AWS Lambda 中
工作流程如下:
获取 https 链接 --> 写入文件系统 --> 从文件系统读取 --> 获取 sha256 哈希值。
它在运行节点 10.15.3 的本地机器上运行良好,但是当我在 AWS 上启动 lambda 函数时,输出为空。 可读流可能存在一些问题。这是代码。您可以直接在本地计算机上运行它。它将根据需要输出 sha256 哈希值。如果您希望在 AWS Lambda 上运行,请按标记注释/取消注释。
//Reference: https://stackoverflow.com/questions/11944932/how-to-download-a-file-with-node-js-without-using-third-party-libraries
var https = require('https');
var fs = require('fs');
var crypto = require('crypto')
const url = "https://upload.wikimedia.org/wikipedia/commons/a/a8/TEIDE.JPG"
const dest = "/tmp/doc";
let hexData;
async function writeit(){
var file = fs.createWriteStream(dest);
return new Promise((resolve,reject) => {
var responseSent = false;
https.get(url,response => {
response.pipe(file);
file.on('finish',() =>{
file.close(() => {
if(responseSent) return;
responseSent = true;
resolve();
});
});
}).on('error',err => {
if(responseSent) return;
responseSent = true;
reject(err);
});
});
}
const readit = async () => {
await writeit();
var readandhex = fs.createReadStream(dest).pipe(crypto.createHash('sha256').setEncoding('hex'))
try {
readandhex.on('finish',function () { //MAY BE PROBLEM IS HERE.
console.log(this.read())
fs.unlink(dest,() => {});
})
}
catch (err) {
console.log(err);
return err;
}
}
const handler = async() =>{ //Comment this line to run the code on AWS Lambda
//exports.handler = async (event) => { //UNComment this line to run the code on AWS Lambda
try {
hexData = readit();
}
catch (err) {
console.log(err);
return err;
}
return hexData;
};
handler() //Comment this line to run the code on AWS Lambda
解决方法
您可能需要检查多项内容。
-
由于您访问的 URL 是公开的,因此请确保您的 lambda 位于 VPC 之外,或者您的 VPC 具有连接互联网访问权限的 NAT 网关。
-
/tmp
是 lambda 的有效临时目录,但您可能需要在使用它之前在doc
内创建/tmp
文件夹。
您可以查看 cloud-watch 日志,了解有关启用后会发生什么的更多信息。
,我以前见过 local 和 lambda 之间的这种行为差异。
所有异步函数都返回承诺。必须等待异步函数。在不等待的情况下调用异步函数意味着继续执行到下一行,并且可能在调用函数之外执行。
所以你的代码:
exports.handler = async (event) => {
try {
hexData = readit();
}
catch (err) {
console.log(err);
return err;
}
return hexData;
};
readit()
被定义为 const readit = async () => { ... }
。但是您的处理程序不会等待它。因此,hexData = readit();
将未解决的承诺分配给 hexData
,将其返回,然后处理程序退出,Lambda “完成”,而 readit()
的代码尚未执行。
简单的解决方法是等待异步函数:hexData = await readit();
。它在 node 本地工作的原因是因为 node 进程会在退出之前等待 promise 解决,即使处理程序函数已经返回。但是由于 Lambda 在处理程序返回后立即“返回”,因此未解决的承诺仍然未解决。 (顺便说一句,writeit
函数不需要被标记为异步,因为它不等待任何东西,并且已经返回了一个承诺。)
话虽如此,我不太了解承诺,而且我对事件几乎一无所知。所以还有其他事情会为我引发警告标志,但我不确定它们,也许它们完全没问题,但我会在这里提出以防万一:
file.on('finish'
和 readandhex.on('finish'
。这些都是事件,我相信它们是非阻塞的,那么为什么处理程序和 lambda 会等待它们呢?
在第一种情况下,它在一个 promise 中,并且 resolve()
在事件函数中被调用,所以这可能没问题(正如我所说,我对这两个主题不太了解,所以我不确定) - 重要的是代码必须在那个点阻塞,直到承诺得到解决。如果代码可以继续执行(即从 writeit()
返回),直到引发 finish
事件,则它不会工作。
第二种情况几乎肯定会有问题,因为它只是说 if x 事件被引发,then do y。没有等待的承诺,所以没有什么可以阻止代码,所以它会很高兴地继续到 readit()
函数的末尾,然后是处理程序和 lambda。同样,这是基于事件是非阻塞的假设(从某种意义上说,您要在某个事件上执行某些代码的声明,不会在该点等待引发该事件)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。