AWS Lambda Invoke不执行lambda函数

我创build了4个Lambda函数来处理将写入MySQL表的信息。 前三个函数分别select插入和更新一个MYSQL表logging。

然后我创build了第四个函数来接受logging细节作为事件参数的一部分。 这个函数首先尝试通过调用第一个lambda函数来selectlogging,如果find它,将使用更新lambda函数更新表上的logging。 如果没有find它,它将调用插入函数来添加logging。 我正在使用操作MySQL表的3个函数pool.query。 我也使用lambda.invoke从第四个函数调用这三个函数。

我能够通过传递logging细节作为参数成功地在本地testing第四个函数,并且能够成功调用三个Lambda函数并更新mySQL表logging。 我遇到的问题是,当我在AWS Lambda中上传函数时,它不会调用这三个函数中的任何一个。 我没有看到日志中的任何错误,所以我不知道如何检查问题出在哪里。 以下是调用其他函数的y代码:

exports.handler = (event, context, callback) => { var err = null; var payload = { qryString : event.qryString, record: event.updaterecord, dbConfigPool : event.dbConfigPool } var params = { FunctionName: 'getInventory', Payload: JSON.stringify(payload) } console.log(' before invoke ' + JSON.stringify(params) ) lambda.invoke(params, function(err, data) { console.log(' aftr invoke ' + JSON.stringify(params) ) if (err) { console.log('err ' + err, err.stack); // an error occurred event.message = err + ' query error'; } else { console.log('success' + JSON.stringify(data)); console.log(' status code ' + JSON.stringify(data.StatusCode)); console.log(' Payload ' + JSON.stringify(JSON.parse(data.Payload))); var rowsTemp = JSON.parse(data.Payload); var rows = rowsTemp.data; if (!rowsTemp.recordExist) { console.log('insert') // Update inventory record only if quantity is not negative var newQuantity = 0 newQuantity = parseFloat(event.updaterecord.quantity); if (Math.sign(newQuantity) === 1) { var payload = { record: event.updaterecord, dbConfigPool : event.dbConfigPool } console.log('insert' + JSON.stringify(payload)); var params = { FunctionName: 'insertInventory', Payload: JSON.stringify(payload) } lambda.invoke(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response }); } } else { newQuantity = 0 newQuantity = parseFloat(event.updaterecord.quantity) + parseFloat(rows[0].quantity); if (Math.sign(newQuantity) === 1) { event.updaterecord.quantity = newQuantity; } else { // Set to zero if the result is negative event.updaterecord.quantity = 0; } console.log('value ' + JSON.stringify(newQuantity) + ' updaterecord' + JSON.stringify(event.updaterecord.quantity) ); var payload = { qryString : event.qryString, record: event.updaterecord, dbConfigPool : event.dbConfigPool } console.log('update' + JSON.stringify(payload)); var params = { FunctionName: 'updateInventory', Payload: JSON.stringify(payload) } console.log(' before invoke ' + JSON.stringify(params) ) lambda.invoke(params, function(err, data) { console.log(' after invoke ' + JSON.stringify(params) ) if (err) { console.log('err ' + err, err.stack); // an error occurred event.message = err + ' query error'; } else { console.log(data); } // else }); // lambda invoke } } // successful response }); console.log(' end of function'); var completed = true; context.callbackWaitsForEmptyEventLoop = false; callback(null, completed); } 

道歉,如果代码很长。 但是我想表明我确实已经放了一些console.logs来监视通过哪里。 cloudwatch日志只显示第一个lambda.invoke之前的第一条消息,然后显示函数结尾的最后一条消息。

我也没有在cloudwatch中看到任何已经被调用的三个函数的日志条目。

06/17好的,因为我仍然无法完成这项工作,所以我将代码简化为以下内容:

 exports.handler = (event, context, callback) => { var err = null; var updatedRecord = false; var responseDetail = {}; var payload = { qryString : event.qryString, record: event.updaterecord, dbConfigPool : event.dbConfigPool } var params = { FunctionName: 'getInventory', Payload: JSON.stringify(payload) } console.log(' before invoke ' + JSON.stringify(params)); lambda.invoke(params, function(err, data) { if (err) { event.message = err + ' query error'; callback(err,event.message); } else { console.log('success' + JSON.stringify(data)); console.log(' status code ' + JSON.stringify(data.StatusCode)); console.log(' Payload ' + JSON.stringify(JSON.parse(data.Payload))); callback(null, data); } // successful response }); console.log(' end of function'); // var completed = true; // context.callbackWaitsForEmptyEventLoop = false; // callback(null, completed); } 

但是,当我做testing的时候,这个函数会超时。 我还赋予完整的Lambda和RDS访问权限。

首先 – 欢迎回拨地狱! 稍后我会回到这个。

这是一个调用lambda函数的简单代码。

 var params = { FunctionName: 'LAMBDA_FUNCTION_NAME', /* required */ }; lambda.invoke(params, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log(data); // successful response } }); 

lambda.invoke函数有两个参数( paramsfunction(err,data){..} )。 第一个是一个简单的JSON对象。 第二个是一个函数 – 一个callback函数。 当执行lambda.invoke(你可以认为LAMBDA_FUNCTION_NAME)结束时,这个函数将被“callback”。 如果发生错误,将被“存储”在errvariables中,否则返回的数据将被存储在数据variables中(这不是正确的解释,但我试图在这里保持简单)。

当你想要一个接一个地调用两个lambda函数时会发生什么?

 var params1 = { FunctionName: 'LAMBDA_FUNCTION_1_NAME', /* required */ }; lambda.invoke(params1, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log('Lambda function 1 invoked!'); console.log(data); // successful response } }); var params2 = { FunctionName: 'LAMBDA_FUNCTION_2_NAME', /* required */ }; lambda.invoke(params2, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log('Lambda function 2 invoked!'); console.log(data); // successful response } }); console.log('I am done!'); 

根据LAMBDA_FUNCTION_1_NAME和LAMBDA_FUNCTION_2_NAME的执行时间,您可能会看到不同的输出:

 Lambda function 1 invoked! I am done! 

要么

 Lambda function 1 invoked! Lambda function 2 invoked! I am done! 

甚至

 Lambda function 1 invoked! I am done! Lambda function 2 invoked! 

这是因为你正在调用lambda.invoke,之后(不等),你再次调用lambda.invoke。 之后(当然没有等待)前面的函数结束你调用console.log('我完成!');

您可以通过将每个函数放在前一个函数的callback中来解决这个问题。 像这样的东西:

 var params1 = { FunctionName: 'LAMBDA_FUNCTION_1_NAME', /* required */ }; lambda.invoke(params1, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log('Lambda function 1 invoked!'); console.log(data); // successful response var params2 = { FunctionName: 'LAMBDA_FUNCTION_2_NAME', /* required */ }; lambda.invoke(params2, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log('Lambda function 2 invoked!'); console.log(data); // successful response console.log('I am done!'); } }); } }); 

这样你的输出将是:

 Lambda function 1 invoked! Lambda function 2 invoked! I am done! 

但是,如果你想要一个接一个地调用3个或更多的函数,那么你将会得到嵌套的代码。 这是callback地狱。 你可以用这种方式重写你的代码。 但在我看来,检查瀑布asynchronous库是一个好主意

 async.waterfall([ function(callback) { callback(null, 'one', 'two'); }, function(arg1, arg2, callback) { // arg1 now equals 'one' and arg2 now equals 'two' callback(null, 'three'); }, function(arg1, callback) { // arg1 now equals 'three' callback(null, 'done'); } ], function (err, result) { // result now equals 'done' }) 

伪代码应该像这样:

 async.waterfall([ function(callback1) { var params1 = { FunctionName: 'LAMBDA_FUNCTION_1_NAME', /* required */ }; lambda.invoke(params1, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log('LAMBDA_FUNCTION_1_NAME finished!'); callback1(null,data); } }); }, function(result_from_function_1, callback2) { console.log(result_from_function_1); // outputs result from LAMBDA_FUNCTION_1_NAME var params2 = { FunctionName: 'LAMBDA_FUNCTION_2_NAME', /* required */ }; lambda.invoke(params2, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log('LAMBDA_FUNCTION_2_NAME finished!'); callback2(null,data); } }); }, function(result_from_function_2, callback3) { console.log(result_from_function_2); // outputs result from LAMBDA_FUNCTION_2_NAME var params3 = { FunctionName: 'LAMBDA_FUNCTION_3_NAME', /* required */ }; lambda.invoke(params3, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log('LAMBDA_FUNCTION_3_NAME finished!'); callback3(null,data); } }); } ], function (err, result) { // result now equals LAMBDA_FUNCTION_3_NAME result }) 

请注意,所有的callback函数(callback1,callback2和callback3)都只能使用名字“callback”。 为了更好的理解,我改了名字。

想想这是干什么的:

 lambda.invoke(params, function(err, data) { ... 

它开始“做某事”(事实上是调用另一个lambda函数实际上是不重要的),当“某事”完成时,它调用函数(),对不对?

但它也立即返回,并执行下一个语句。

同时,“asynchronous”事件由asynchronous事件循环处理。

“下一个陈述”是

 console.log(' end of function'); 

然后,你告诉lambda“嘿,我可能会有一些asynchronous的东西,但不要担心等待它完成”:

 context.callbackWaitsForEmptyEventLoop = false; 

所以好消息是你的代码正在做什么是写的做…但事实certificate是错误的。

到处都有这两件事之一

 // an error occurred // successful response 

这些是您应该调用callback() ,而不是处理函数的结尾处,您的代码很快就会到达,正如它应该的那样。

你不应该需要使用context.callbackWaitsForEmptyEventLoop = false; 如果你正确断开你的数据库连接,你所包含的所有模块都可以正常工作。 虽然这有其目的,但似乎有很多人用它来掩盖微妙的未完成的业务。

或者,对于一个更加整洁的解决scheme,你最后只提到一个callback函数,你的函数{function {function {nesting不会失去控制,使用async-waterfall