Lambda集成DynamoDB与SNS超时求助:执行成功但反复重试
问题根源分析
从你的日志和代码来看,核心问题是无限递归调用getmsg函数,加上异步操作的回调时机错误,导致Lambda函数一直在循环执行DynamoDB查询和SNS发送,直到触发10秒超时限制。
具体问题点拆解:
- 无限递归:你的
getmsg函数在DynamoDB成功/失败的回调里,又再次调用了getmsg,形成了无限循环。日志里重复出现的Dynamo Success和push sent就是明证——函数一直在反复执行相同的操作,停不下来。 - Callback调用过早:你在handler里直接同步调用了
callback(null, {statusCode:200}),这会让Lambda认为函数已经执行完成,但实际上DynamoDB和SNS的异步操作还在后台运行,加上递归的无限循环,事件队列一直被占满,最终导致超时。 context.callbackWaitsForEmptyEventLoop设置位置错误:这个参数需要在handler的最开始设置,而且因为无限递归的存在,即使设置正确,事件循环也永远不会清空,所以这个配置起不到作用。- 变量作用域混乱:
MESSAGE_ID的定义和传递逻辑混乱,函数参数和内部变量重名,导致逻辑出错。
修复方案
下面是修正后的代码,解决了上述所有问题:
exports.handler = function (event, context, callback) { // 首先设置这个参数,放在handler最开头 context.callbackWaitsForEmptyEventLoop = false; var AWS = require('aws-sdk'); var doc = require('dynamodb-doc'); var dynamodb = new doc.DynamoDB(); var sns = new AWS.SNS({ region:'eu-west-1', maxRetries: 0 }); var params = { TableName : 'abcmsg', ProjectionExpression: 'Message', Key : { "ind" : "ABC10" } }; // 重构getmsg为单次执行的异步函数,去掉递归 function getmsg() { dynamodb.getItem(params, function (err, data) { if (err) { console.log('ERROR: Dynamo Failed:', err); // 出错时调用callback返回错误 return callback(err); } console.log('Dynamo Success: ' + JSON.stringify(data, null, ' ')); const MESSAGE_ID = data['Item'].Message; console.log('data', MESSAGE_ID); // 发送SNS通知,在SNS回调里结束Lambda函数 sns.publish({ Message: MESSAGE_ID, Subject:"Test Message", TopicArn:"arn:aws:sns:eu-west-1:0123456789012:Lambda" }, function (err, snsData) { if (err) { console.log(err.stack); return callback(err); } console.log('push sent'); // 所有异步操作完成后,调用callback结束函数 callback(null, { "statusCode": 200 }); }); }); } // 调用一次getmsg,不再递归 getmsg(); };
关键修复点说明
- 移除无限递归:
getmsg现在只执行一次DynamoDB查询,查询完成后执行SNS发送,不再自我调用。 - 正确的Callback时机:只有当SNS发送完成(成功或失败)后,才调用
callback,让Lambda知道函数真正执行完毕。 - 调整
context.callbackWaitsForEmptyEventLoop位置:放在handler最开始,确保Lambda在callback调用后不会等待事件循环清空(不过现在我们的逻辑里所有异步操作都在callback前完成,这个配置其实可以去掉,但保留也没问题)。 - 清理变量作用域:统一
MESSAGE_ID的定义,避免变量名冲突。
这样修改后,函数会执行一次DynamoDB查询,发送一次SNS通知,然后正常结束,不会再出现超时和重复执行的问题。
内容的提问来源于stack exchange,提问作者arjain13
相关产品推荐
相关产品推荐

