【问题标题】:node.js Lambda only runs once (all subsequent attempts fail)node.js Lambda 只运行一次(所有后续尝试都失败)
【发布时间】:2021-09-08 06:39:00
【问题描述】:

我的 lambda 尝试执行以下操作: 给定 S3 中的特定对象:即时解压缩,并从中解析出一些文本 (UUID)。

我的问题是它只能工作一次。这是我的代码

const aws = require('aws-sdk');
const gzip = require('zlib').createGunzip();
const s3 = new aws.S3({region: 'us-east-1', apiVersion: '2006-03-01'});

exports.handler = async (event, context) => {
    const bucket = event.bucket;
    let key = event.key;

    let uuid = '';
    try {
        uuid = await getUuidFromFile(bucket, key);
    }
    catch (err) { console.log("Error!!", err) }

    return {
        statusCode: 200,
        body: JSON.stringify(uuid || {message: `Failed to retrieve UUID for ${deviceName}`})
    }

};

function getUuidFromFile(bucket, key) {
    let string = '';
    let uuid;

    return new Promise((resolve, reject) => {
        s3.getObject({Bucket: bucket, Key: key})
            .createReadStream()
            .pipe(gzip)
            .on('data', (data) => {
                string += data.toString();
            })
            .on('end', () => {
                uuid = parseUUID(string.substring(0, 150));
                console.log("UUID", uuid);
                resolve(uuid);
            })
            .on('err', (err) => {
                reject(err);
            });
    });
}

function parseUUID(data) {
    // do some actual parsing on the data and get the uuid
    return "uuid";
}

当我部署我的 lambda 并针对特定密钥运行它时 - 它可以工作:找到文件、解压缩、解析并返回 UUID。 SAME 键的任何后续运行都不会返回任何内容。

【问题讨论】:

  • 你是如何运行这个 Lambda 函数的?您是否会为每次调用 Lambda 函数获取 CloudWatch Logs?您是否在函数中添加了日志记录以尝试找出它未能返回预期结果的原因?
  • @jarmod 我正在使用测试功能运行 lambda 函数。我提交了相同的有效负载 - 第一次工作,但下一次尝试失败。 CloudWatch 日志可用,但未报告任何内容(所有 lambda 运行都标记为成功)。我每隔一行都撒了console.log,我发现它进入了getUuidFromFile函数,但没有显示其他日志语句。
  • 奇怪。作为仅供参考,如果您只想要对象的前 150 个字节,您可以发出远程获取。这将节省您不必要地阅读一个非常大的对象的全部内容。

标签: javascript node.js amazon-s3 aws-lambda


【解决方案1】:

我想明白了。

之前:

const gzip = require('zlib').createGunzip();
...
s3.getObject({Bucket: bucket, Key: key})
        .createReadStream()
        .pipe(gzip)

之后:

const zlib = require('zlib');
...
s3.getObject({Bucket: bucket, Key: key})
        .createReadStream()
        .pipe(zlib.createGunzip())

就是这样!现在它每次都能完美运行。我怀疑这可能与Lambda execution environment 有关?无论哪种方式,在顶部声明createGunzip(),而不是每次我调用函数时,都是问题所在。

【讨论】:

  • 好的,这是有道理的。 Lambda 函数热启动不会重新运行源模块中的初始化代码;他们重新使用以前的运行时环境,然后简单地调用函数处理程序。因此,任何“全局”变量都会保留其在上次调用 Lambda 函数结束时的值。
猜你喜欢
  • 2020-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-01
  • 2016-05-29
  • 2014-10-05
  • 1970-01-01
相关资源
最近更新 更多