AWS Lambda似乎在完成之前退出 [英] AWS Lambda seems exiting before completion

查看:100
本文介绍了AWS Lambda似乎在完成之前退出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的lambda函数(nodeJS),它将收到的事件放入kinesis流中.这是源代码:

I have a very simple lambda function (nodeJS) which put the event received in kinesis stream. Here is the source code:


    'use strict';

    const AWS = require('aws-sdk');
    const kinesis = new AWS.Kinesis({apiVersion: '2013-12-02'});

    exports.handler = async (event, context, callback) => {
        let body = JSON.parse(event.body);
        let receptionDate = new Date().toISOString();
        let partitionKey = "pKey-" + Math.floor(Math.random() * 10);

        // Response format needed for API Gateway
        const formatResponse = (status, responseBody) => {
            return {
                statusCode: status,
                headers: { "Content-Type": "application/json" },
                body: JSON.stringify(responseBody)
            }
        }

        // body.events is an array of events. Just add the reception date in each events.
        for(let e of body.events) {
            e.reception_date = receptionDate;
        }

        console.log("put In kinesis stream");
        let kinesisParams = {
            Data: new Buffer(JSON.stringify(body) + "\n"),
            PartitionKey: partitionKey,
            StreamName: 'event_test'
        };

        kinesis.putRecord(kinesisParams, (err, res) => {
            console.log("Kinesis.putRecord DONE");
            if(err) {
                console.log("putRecord Error:", JSON.stringify(err));
                callback(null, formatResponse(500, "Internal Error: " + JSON.stringify(err)));
            } else {
                console.log("putRecord Success:", JSON.stringify(res));
                callback(null, formatResponse(200));
            }
        });
    };

执行此代码后,以下是cloudwatch中的日志:

When this code is executed, here are the logs in cloudwatch:

START RequestId: 5d4d7526-1a40-401f-8417-06435f0e5408 Version: $LATEST
2019-01-11T09:39:11.925Z    5d4d7526-1a40-401f-8417-06435f0e5408    put In kinesis stream
END RequestId: 5d4d7526-1a40-401f-8417-06435f0e5408
REPORT RequestId: 5d4d7526-1a40-401f-8417-06435f0e5408  Duration: 519.65 ms Billed Duration: 600 ms     Memory Size: 128 MB Max Memory Used: 28 MB  

似乎未调用kinesis.putRecord ...我在kinesis流日志中看不到任何内容.我肯定在某个地方错了,但是我不知道在哪里!

It seems that kinesis.putRecord is not called... I don't see anything in kinesis stream logs. I'm certainly wrong somewhere, but I don't know where !

推荐答案

kinesis.putRecord是异步操作,它在完成(无论成功还是有错误)时调用回调(第二个参数).

kinesis.putRecord is an asynchronous operation, which calls callback (The second param) when it's finished (whether successful or with an error).

async函数是返回promise的函数.解决了该承诺后,Lambda将完成其执行,即使还有其他异步操作尚未完成. 由于您的函数未返回任何内容,因此当函数结束时,promise将立即得到解决,因此执行将立即完成-无需等待异步kinesis.putRecord任务.

async function is a function that returns a promise. Lambda will finish its execution when this promise is resolved, even if there are other asynchronous operations which are not done yet. Since your function returns nothing, then the promise is immediately resolved when the function ends and therefore the execution will be finished immediately - without waiting to your async kinesis.putRecord task.

使用async处理程序时,不需要调用回调.相反,您将返回所需的内容,或者抛出错误. Lambda会得到它并分别做出响应.

When using an async handler, you don't need to call callback. Instead, you return what ever you want, or throw an error. Lambda will get it and respond respectively.

因此,您在这里有2个选择:

So you have 2 options here:

  1. 由于您的代码中没有任何await,因此只需删除async.在这种情况下,Lambda等待事件循环清空(
  1. Since you don't have any await in your code, just remove the async. In this case Lambda is waiting for the event loop to be emtpy (Unless you explicitly change context.callbackWaitsForEmptyEventLoop)
  2. Change the kinesis.putRecord to something like:

let result;

try {
  result = await kinesis.putRecord(kinesisParams).promise();
} catch (err) {
  console.log("putRecord Error:", JSON.stringify(err));
  throw Error(formatResponse(500, "Internal Error: " + JSON.stringify(err));
}

console.log("putRecord Success:", JSON.stringify(result));
return formatResponse(200);

在第二个选项中,lambda将继续运行,直到完成kinesis.putRecord.

In the second option, the lambda will keep running until kinesis.putRecord is finished.

有关这种情况下Lambda行为的更多信息,您可以在lambda容器中的/var/runtime/node_modules/awslambda/index.js下查看执行处理程序的主要代码.

For more information about Lambda behavior in this case, you can see the the main code which execute your handler under /var/runtime/node_modules/awslambda/index.js in the lambda container.

这篇关于AWS Lambda似乎在完成之前退出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆