-1

这是工作流程:

获取 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

4

2 回答 2

0

您可能需要检查多项内容。

  1. 由于您正在访问的 URL 是公共 URL,因此请确保您的 lambda 在 VPC 之外,或者您的 VPC 具有连接互联网访问权限的 NAT 网关。

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

您可以查看 cloud-watch 日志以获取有关启用后发生的情况的更多信息。

于 2020-12-24T19:20:56.097 回答
0

我之前已经看到本地和 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()执行代码。

简单的解决方法是等待 async 函数:hexData = await readit();. 它在 node 本地工作的原因是因为 node 进程将在退出之前等待 promise 解决,即使处理函数已经返回。但是由于 Lambda 在处理程序返回后立即“返回”,因此未解决的承诺仍然未解决。(顺便说一句,不需要将writeit函数标记为异步,因为它不等待任何东西,并且已经返回了一个 Promise。)

话虽如此,我不太了解承诺,而且我对事件几乎一无所知。所以还有其他一些事情对我来说是警告标志,但我不确定它们,也许它们完全没问题,但我会在这里提出它以防万一:

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

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

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

于 2020-12-25T11:14:24.043 回答