当您异步调用函数时,Lambda 会将事件发送到队列。一个单独的进程会从队列中读取事件并运行您的函数。将事件添加到队列后,Lambda 将返回成功响应,而不返回其他信息。要异步调用函数,请将调用类型参数设置为 Event
。
输出文件 (response.json
) 不包含任何信息,但运行此命令时仍会创建该文件。如果 Lambda 无法将事件添加到队列,则错误消息将显示在命令输出中。
Lambda 管理函数的异步调用队列,并尝试自动重试失败的事件。如果函数返回错误,Lambda 会尝试再运行两次,前两次尝试之间等待一分钟,第二次与第三次之间等待两分钟。函数错误包括函数代码返回的错误,以及函数运行时返回的错误,例如超时。如果所有 3 次尝试都失败,Lambda 会将事件发送到死信队列(如果已配置)。
如果该函数没有足够的并发可用于处理所有事件,则其他请求将受到限制。对于限制错误 (429) 和系统错误(500 系列),Lambda 会将事件返回到队列并尝试再次运行该函数长达 6 小时。重试间隔从第一次尝试后的 1 秒呈指数级增加到最多 5 分钟,但如果队列已备份,则可能会更长。Lambda 还降低了从队列中读取事件的速率,并且可能无法读取队列中进一步返回的事件。事件可以位于队列中的最长时间是 4 天。
即使您的函数没有返回错误,它也可能多次从 Lambda 接收相同的事件,因为队列本身具有最终一致性。如果函数无法跟上传入事件,则也可能从队列中删除事件而不将其发送到函数。确保您的函数代码正常处理重复事件,并且您有足够的并发可用于处理所有调用。
AWS Lambda 函数死信队列
当所有三次尝试处理异步调用失败后,Lambda 可以将事件发送到 Amazon SQS 队列或 Amazon SNS 主题。使用死信队列配置您的函数,以保存这些事件供进一步处理。
如果您没有队列或主题,请创建一个队列或主题。选择与您的使用案例匹配的目标类型。
-
Amazon SQS 队列 – 队列会保存失败的事件,直到它们被检索为止。您可以手动检索事件,也可以配置 Lambda 以从队列中读取并调用函数。
在 Amazon SQS 控制台中,创建一个队列。
-
Amazon SNS 主题 – 主题将失败的事件中继到一个或多个目标。您可以配置主题以将事件发送到电子邮件地址、Lambda 函数或 HTTP 终端节点。
在 Amazon SNS 控制台中,创建一个主题。
要将事件发送到队列或主题,您的函数需要其他权限。添加具有函数执行角色所需权限的策略。
-
Amazon SQS – sqs:SendMessage
-
Amazon SNS – sns:Publish
创建目标并更新函数的执行角色后,将死信队列添加到函数中。您可以配置多个函数,以便将事件发送到同一目标。
配置死信队列
-
打开 Lambda 控制台 函数页面。
-
选择函数。
-
在 Debugging and error handling (调试和错误处理) 下,将 DLQ 资源设置为 Amazon SQS 或 Amazon SNS。
-
选择目标队列或主题。
-
选择 Save。
要通过 AWS CLI 配置死信队列,请使用 update-function-configuration
命令。
$ aws lambda update-function-configuration --function-name my-function \
--dead-letter-config TargetArn=arn:aws:sns:us-east-2:123456789012:my-topic
Lambda 按原样将事件发送到死信队列,并在属性中包含其他信息。您可以使用此信息来标识函数返回的错误,或将事件与日志或 AWS X-Ray 跟踪相关联。
DLQ 消息属性
-
RequestID(字符串)– 调用请求的 ID。请求 ID 显示在函数日志中。您还可以使用 X-Ray 开发工具包在跟踪中的属性上记录请求 ID,然后您可以在 X-Ray 控制台中按请求 ID 进行搜索。有关示例,请参阅错误处理器示例。
-
ErrorCode(数字)– HTTP 状态代码。
-
ErrorMessage(字符串)– 错误消息的第一个 1 KB 文本块。
如果 Lambda 无法向死信队列发送消息,则会删除该事件并发出 DeadLetterErrors 指标。之所以发生这种情况,可能是由于缺少权限,或者消息的总大小超过目标队列或主题的限制。例如,如果正文接近 256 KB 的 Amazon SNS 通知触发导致错误的功能,则 Amazon SNS 添加的附加事件数据与 Lambda 添加的属性相结合,可能会导致消息超过 DLQ 中允许的最大大小。
如果您使用 Amazon SQS 作为事件源,请在 Amazon SQS 队列本身上而不是 Lambda 函数上配置 DLQ。