在 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

您可能需要检查多个事项。

  1. 由于您正在访问的 URL 是公有 URL,因此请确保您的 lambda 位于 VPC 外部,或者您的 VPC 具有附加了具有互联网访问权限的 NAT 网关。

  2. /tmp是 lambda 的有效临时目录,但在使用它之前,您可能需要在/tmp中创建doc文件夹。

可以检查云监视日志,了解有关启用后发生的情况的详细信息。

我以前见过本地和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();。它在节点中本地工作的原因是,即使处理程序函数已经返回,节点进程也会在退出之前等待承诺解析。但是,由于 Lambda 会在处理程序返回后立即"返回",因此未解决的承诺仍未解决。(顺便说一句,writeit函数不需要标记为异步,因为它不等待任何内容,并且已经返回了一个承诺。

话虽如此,我不太了解承诺,我对事件几乎一无所知。所以还有其他事情为我发出警告标志,但我不确定它们,也许它们很好,但我会在这里提出以防万一:

file.on('finish'readandhex.on('finish'.这两个事件,我相信是非阻塞的,那么为什么处理程序和 lambda 会等待它们呢?

在第一种情况下,它是在一个承诺内,resolve()是从事件函数中调用的,所以这可能很好(正如我所说,我对这两个主题了解不多,所以不确定) - 重要的是代码必须在这一点上阻塞,直到承诺得到解决。如果代码可以继续执行(即从writeit()返回),直到引发finish事件,那么它将不起作用。

第二种情况几乎肯定会是一个问题,因为它只是说如果x 事件被引发,那么做 y。没有等待的承诺,所以没有什么可以阻止代码,所以它会很高兴地继续到readit()函数的末尾,然后是处理程序和 lambda。同样,这是基于事件是非阻塞的假设(从某种意义上说,你想要对某个事件执行某些代码的声明不会等待该事件的引发)。

相关内容

  • 没有找到相关文章

最新更新