【问题标题】:AWS Cognito lambda triggers twiceAWS Cognito lambda 触发两次
【发布时间】:2019-06-12 10:46:59
【问题描述】:

我正在使用 AWS Lambda 函数(使用 nodejs)。

一旦 APP 向 Cognito 发出任何请求以注册用户。 然后我设置了 预注册触发器 来验证用户的客户并检查我们数据库中是否可用的用户自定义属性。如果是,则返回错误,否则在 DB 中插入新记录并将事件返回给 Cognito。

TimeoutInfo - 5 分钟。

它在请求中的某个时候发生,而不是一直发生。 RequestId 不同。 (有时会触发 3 次,大部分时间会触发 2 次)

Lambda 触发代码如下。

用户/index.js

const handler = async (event, context) => {
  log.info('createUserLambda:start');
  // immediately return once the call back is called to avoid
  // lambda time out because of any open db connections
  context.callbackWaitsForEmptyEventLoop = false;
  return await preUserCreate(event);
};

exports.handler = 处理程序; 用户/users.js

export const preUserCreate = async (event) => {
  log.info('preUserCreate:Start');
  let userAttributes = event.request.userAttributes;
  const currentDate = moment().utc().format('YYYY-MM-DD HH:mm:ss');
  try {
    let userParams = {
      'docStatus': 'VRF'
    };
    let docParams = [{
      'docNumber': userAttributes['custom:document_number'] ? userAttributes['custom:document_number'] : '',
      'createdDate': currentDate
    }];
    if (docParams.length && docParams[0].docNumber) {
      let documentExit = await getDocs(docParams[0].docNumber);
      if (documentExit.length) {
        log.info('preUserCreate:Error');
        throw new Error('Document number already exist.');;
      }
    }

    let documentRs = await insertDocument(docParams);
    userParams = {
      'did': documentRs[0].id,
      'id': event.userName,
      'createdDate': currentDate,
      'updatedDate': currentDate,
      ...userParams
    };
    let userRs = await insertUser([userParams]);
    if (docParams.length && docParams[0].docNumber) {
      let resultData = await getUserAccountFromAPI(docParams[0].docNumber);
      if (resultData) {
        let foramattedData = await formattedAccountsData(resultData, userRs[0].id, documentRs[0].id);
        await insertUserAccounts(foramattedData);
      }
    }
    log.info('preUserCreate:Success');
    event.response = {
      'autoConfirmUser': false,
      'autoVerifyPhone': false,
      'autoVerifyEmail': false
    };
    return event;
  } catch (error) {
    log.info('preUserCreate:Error', error);
    throw (error);
  }
}

【问题讨论】:

  • 向我们展示 lambda 的触发器!

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


【解决方案1】:

这可能是因为 Cognito 对集成 Lambda 施加了 5 秒的执行超时 - 并且无法更改。另请注意,Cognito 将(重新)尝试调用该函数的最大次数为 3 次。

Customizing User Pool Workflows with Lambda Triggers 部分中声明:

重要 Amazon Cognito 同步调用 Lambda 函数。什么时候 调用,您的 Lambda 函数必须在 5 秒内响应。如果确实如此 不是,Amazon Cognito 会重试调用。 3次尝试失败后, 函数超时。此 5 秒超时值无法更改。

因此,为了减少执行时间,值得考虑在可能的情况下引入缓存。包括数据库连接等。

但请注意,您几乎无法控制 Lambda 的重复使用频率和重新启动频率,您需要在预热时间方面牢记这一点。

【讨论】:

  • 我相信 cognito 尝试执行 lambda 的次数是 4 倍。至少这是我注意到的,我总是在 cloudwatch 中得到 4 条记录
  • 和我一样。我在触发器中启动了一个数据库创建事务,每次都得到 4 条记录。
【解决方案2】:

您是否有可能在 VPC 中运行您的 lambda?我已经看到了在冷启动时在 VPC 中运行的 Cognito 触发器的类似行为。一旦 lambda 变热,问题就消失了

我的预感是 Cognito 内部有一个很短的超时时间来执行触发器,如果​​触发器没有及时回复,它会自动重试。

我们最终不得不向触发器添加逻辑来测试这种情况,这样我们就不会重复写入数据库。

【讨论】:

  • 嘿@Brian,我们面临着完全相同的问题。你还记得你们使用的解决方法吗?还是谢谢
  • @quartaela 由于我们的 lambda 正在获取 Cognito 用户数据并将其写入 SQL 数据库,因此我们只是检查了数据是否尚未插入。
  • 感谢布赖恩的回复。这是否意味着您的 Lambda 至少会被触发两次? Cognito 将从第一次调用中获得超时,但用户数据将在内部插入。 Cognito 将再次触发它,它将检查数据库并在 5 秒内返回有效响应
  • @quartaela 是的,基本上就是这样
猜你喜欢
  • 2016-04-19
  • 2023-01-01
  • 2020-04-24
  • 2018-03-11
  • 2020-08-15
  • 2018-03-10
  • 1970-01-01
  • 2018-03-04
  • 2018-04-02
相关资源
最近更新 更多