AWS Lambda函数多次处理相同的dynamodb流。我错过了什么?

时间:2017-02-21 11:22:36

标签: javascript node.js amazon-web-services amazon-dynamodb aws-lambda

我编写了一个node.js lambda函数,当新记录插入特定表时,该函数根据dynamodb流触发。

该函数仅接收新事件,插入记录的过滤器,然后对于每个记录,使用几个字段从其他表中检索数据。使用该组合数据,组成消息并通过SNS发送到特定目标ARN。

该功能正常运行。检索所有相关数据,并发送推送通知。

但是,由于某种原因,该函数似乎被多次调用同一个流,并多次处理新插入的记录。结果是目标设备多次接收相同的推送通知。

我应该将回调放在不同的地方,还是我没有正确地调用上下文?

这是功能:

'use strict';

var AWS = require("aws-sdk");
var dynamodb = new AWS.DynamoDB();
var sns = new AWS.SNS();

console.log('Loading function');

exports.handler = (event, context, callback) => {
  console.log('Received event:', JSON.stringify(event, null, 2));

  event.Records.forEach((record) => {
    console.log(record.eventID);
    console.log(record.eventName);
    console.log('DynamoDB Record: %j', record.dynamodb);

    if (record.eventName == 'INSERT') {
      var matchId = record.dynamodb.NewImage.eventId.S;
      var match_params = {
        Key: {
          "eventId": {
            S: matchId
          }
        },
        TableName: "xxxxxxxxxxx-mobilehub-xxxxxxx-Event"
      };

      //retrieve the match information from Event table
      dynamodb.getItem(match_params, function(err, data) {
        var match_description = "";
        if (err) {
          console.log(err, err.stack);
          context.fail('No match event record found in Event table');
        } else {
          match_description = data.Item.description.S;

          var uId = record.dynamodb.NewImage.participantUserId.S; //participantUserId 
          var user_params = {
            Key: {
              "userId": {
                S: uId
              }
            },
            TableName: "xxxxxxxxxxx-mobilehub-xxxxxxxxx-User"
          };

          //retrieve the user record from User table
          dynamodb.getItem(user_params, function(err, data) {
            if (err) {
              console.log(err, err.stack); // an error occurred  
              context.fail('Error occurred. See log.');
            } else {
              console.log(data); // successful response
              if (data.length === 0) {
                console.log("No User Record Found.");
                context.fail('No user found for participantUserId.');

              } else {

                var deviceARN = data.Item.device_arn.S;
                if (deviceARN <= 1) {
                  console.log("User has not registered their device for push notifications.");
                  context.fail('User has not registered for notifications');
                } else {

                  var json_message = JSON.stringify({
                    APNS_SANDBOX: JSON.stringify({
                      aps: {
                        alert: "You are playing in an upcoming match " + match_description,
                        badge: 1,
                        sound: 'default'
                      }
                    })
                  });

                  var snsparams = {
                    Message: json_message,
                    MessageStructure: 'json',
                    TargetArn: deviceARN
                  };

                  sns.publish(snsparams, function(err, data) {
                    if (err) {
                      console.log(err); // an error occurred
                      context.fail('SNS send failed. See log.');
                    } else {
                      console.log(data); // successful response
                      context.success('Push notification sent to user.');
                    }
                  });
                }
              }
            }
          });
        }
      });
    }
  });
  callback(null, `Successfully processed ${event.Records.length} records.`);
};

2 个答案:

答案 0 :(得分:0)

就我而言,我多次添加了相同的事件源。

与AWS支持工程师的对话中的报价:

使用我的内部工具,我注意到Lambda函数xxxxxx具有 事件来源: arn:aws:events:my_region:my_acct_id:rule / my_event_target 配置两次作为推送事件源。这意味着这可能是原因 为什么每分钟都会看到两次调用。你能不能 在您这边确认是否为$ LATEST配置了两次此事件 版本的lambda,并确认是否符合要求?

我希望这可以节省一些时间:)

答案 1 :(得分:0)

在底部的lambda页面中,尝试将“并发”未保留的帐户并发调整为1,将“异步调用”重试尝试调整为0。作为测试,请尝试这些并观察其行为。可能会有帮助。