AWS Cognito lambda 触发两次
Posted
技术标签:
【中文标题】AWS Cognito lambda 触发两次【英文标题】:AWS Cognito lambda triggers twice 【发布时间】: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 的触发器! 【参考方案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 是的,基本上就是这样以上是关于AWS Cognito lambda 触发两次的主要内容,如果未能解决你的问题,请参考以下文章
在 AWS Cognito 用户池中删除用户时触发 Lambda 函数
AWS Cognito Post-Confirmation [已结束]