异步调用 - AWS Lambda
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

异步调用

多个 AWS 服务(如 Amazon Simple Storage Service (Amazon S3) 和 Amazon Simple Notification Service (Amazon SNS))异步调用函数来处理事件。在异步调用函数时,您不会等待函数代码的响应。您将事件交给 Lambda,Lambda 处理其余部分。您可以配置 Lambda 如何处理错误,并将调用记录发送到下游资源,以将应用程序的组件链接在一起。

下图显示了客户端异步调用函数 Lambda。Lambda 在将事件发送到函数之前对事件进行排队。


      客户端异步调用函数。Lambda 在将事件发送到函数之前对事件进行排队。

对于异步调用,Lambda 将事件放在队列中并返回成功响应,没有附加信息。一个单独的进程会从队列中读取事件并将其发送到函数。要异步调用函数,请将调用类型参数设置为 Event

$ aws lambda invoke --function-name my-function --invocation-type Event --payload '{ "key": "value" }' response.json { "StatusCode": 202 }

输出文件 (response.json) 不包含任何信息,但运行此命令时仍会创建该文件。如果 Lambda 无法将事件添加到队列,则错误消息将显示在命令输出中。

Lambda 管理函数的异步事件队列以及在出错时重试的尝试次数。如果函数返回错误,Lambda 会尝试再运行两次,前两次尝试之间等待一分钟,第二次与第三次尝试之间等待两分钟。函数错误包括函数代码返回的错误,以及函数运行时返回的错误,例如超时。


      Lambda 会记录子段中的每次尝试。

如果该函数没有足够的并发性可用于处理所有事件,则其他请求将受到限制。对于限制错误 (429) 和系统错误(500 系列),Lambda 会将事件返回到队列并尝试再次运行该函数长达 6 小时。在第一次尝试后,重试间隔从 1 秒以指数级增加到最多 5 分钟。但是,如果队列已备份,则时间可能会更长。Lambda 还会降低从队列中读取事件的速率。

以下示例显示事件已成功添加到队列中,但由于限制,一小时后仍处于等待状态。


      限制的请求在 AWS X-Ray 中显示为待处理状态。

即使您的函数没有返回错误,它也可能多次从 Lambda 接收相同的事件,因为队列本身具有最终一致性。如果函数无法跟上传入事件,则也可能从队列中删除事件而不将其发送到函数。确保您的函数代码正常处理重复事件,并且您有足够的并发可用于处理所有调用。

备份队列时,新事件可能会在 Lambda 有机会将它们发送到您的函数之前过期。当事件过期或所有处理尝试都失败时,Lambda 将放弃该事件。您可为函数配置错误处理以减少 Lambda 执行的重试次数,或者更快地放弃未处理的事件。

您还可以配置 Lambda 以将调用记录发送到另一个服务。Lambda 支持以下异步调用目标

  • Amazon SQS – 标准 SQS 队列。

  • Amazon SNS – SNS 主题。

  • AWS Lambda – Lambda 函数。

  • Amazon EventBridge – EventBridge 事件总线。

调用记录包含有关 JSON 格式的请求和响应的详细信息。您可为成功处理的事件以及处理尝试失败的事件配置单独的目标。或者,您可以将 SQS 队列或 SNS 主题配置为丢弃事件的死信队列。对于死信队列,Lambda 只发送事件的内容,不包含有关响应的详细信息。

配置异步调用的错误处理

使用 Lambda 控制台配置有关函数、版本或别名的错误处理设置。

配置错误处理

  1. 打开 Lambda 控制台 函数页面

  2. 选择函数。

  3. Asynchronous invocation (异步调用) 下,选择 Edit (编辑)

  4. 配置以下设置。

    • Maximum age of event (事件的最长期限) – Lambda 在异步事件队列中保留事件的最长时间(最长 6 小时)。

    • Retry attempts (重试次数) – 函数返回错误时 Lambda 重试的次数(0 到 2 之间)。

  5. 选择 Save

当调用事件超过最长期限或所有重试均失败时,Lambda 会丢弃该事件。要保留已丢弃事件的副本,请配置失败事件目标。

配置异步调用目标

要将异步调用记录发送到另一个服务,请向函数添加目标。您可为处理失败的事件和处理成功的事件配置单独的目标。与错误处理设置一样,您可以在函数、版本或别名上配置目标。

以下示例显示正在处理异步调用的函数。如果函数返回了成功响应或退出而未引发错误,则 Lambda 会将调用的记录发送到 EventBridge 事件总线。当事件的所有处理尝试失败时,Lambda 会将调用记录发送到 Amazon SQS 队列。


        Lambda 会根据结果将调用记录发送到队列或事件总线目标。

要将事件发送到目标,您的函数需要其他权限。添加具有函数执行角色所需权限的策略。每项目标服务均需要不同的权限,如下所示:

在 Lambda 控制台的函数设计器中向函数添加目标。

为异步调用记录配置目标

  1. 打开 Lambda 控制台 函数页面

  2. 选择函数。

  3. Designer (设计器) 下,选择 Add destination (添加目标)

  4. 对于 Source (源),选择 Asynchronous invocation (异步调用)

  5. 对于 Condition (条件),请从以下选项中选择:

    • On failure (失败时) – 当事件的所有处理尝试均失败或超过最长期限时发送记录。

    • On success (成功时) – 函数成功处理异步调用时发送记录。

  6. 对于 Destination type (目标类型),请选择接收调用记录的资源类型。

  7. 对于 Destination (目标),请选择一个资源。

  8. 选择 Save

当调用与条件匹配时,Lambda 会向目标发送包含调用详细信息的 JSON 文档。以下示例显示了由于函数错误而导致三次处理尝试失败的事件的调用记录。

例 调用记录

{ "version": "1.0", "timestamp": "2019-11-14T18:16:05.568Z", "requestContext": { "requestId": "e4b46cbf-b738-xmpl-8880-a18cdf61200e", "functionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function:$LATEST", "condition": "RetriesExhausted", "approximateInvokeCount": 3 }, "requestPayload": { "ORDER_IDS": [ "9e07af03-ce31-4ff3-xmpl-36dce652cb4f", "637de236-e7b2-464e-xmpl-baf57f86bb53", "a81ddca6-2c35-45c7-xmpl-c3a03a31ed15" ] }, "responseContext": { "statusCode": 200, "executedVersion": "$LATEST", "functionError": "Unhandled" }, "responsePayload": { "errorMessage": "RequestId: e4b46cbf-b738-xmpl-8880-a18cdf61200e Process exited before completing request" } }

调用记录包含有关事件、响应和记录发送原因的详细信息。

异步调用配置 API

要使用 AWS CLI 或 AWS 开发工具包管理异步调用设置,请使用以下 API 操作。

要使用 AWS CLI 配置异步调用,请使用 put-function-event-invoke-config 命令。以下示例配置一个最长事件期限为 1 小时且无重试的函数。

$ aws lambda put-function-event-invoke-config --function-name error \ --maximum-event-age-in-seconds 3600 --maximum-retry-attempts 0 { "LastModified": 1573686021.479, "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:error:$LATEST", "MaximumRetryAttempts": 0, "MaximumEventAgeInSeconds": 3600, "DestinationConfig": { "OnSuccess": {}, "OnFailure": {} } }

put-function-event-invoke-config 命令覆盖函数、版本或别名上的任何现有配置。要配置某个选项而不重置其他选项,请使用 update-function-event-invoke-config。以下示例配置 Lambda,以便在无法处理事件时将记录发送到名为 destination 的 SQS 队列。

$ aws lambda update-function-event-invoke-config --function-name error \ --destination-config '{"OnFailure":{"Destination": "arn:aws:sqs:us-east-2:123456789012:destination"}}' { "LastModified": 1573687896.493, "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:error:$LATEST", "MaximumRetryAttempts": 0, "MaximumEventAgeInSeconds": 3600, "DestinationConfig": { "OnSuccess": {}, "OnFailure": { "Destination": "arn:aws:sqs:us-east-2:123456789012:destination" } } }

AWS Lambda 函数死信队列

作为失败时的目标的替代,您可以使用死信队列配置函数,以保存丢弃的事件供进一步处理。死信队列的作用与失败时的目标相同,在某个事件的所有处理尝试都失败或者已过期而未处理时使用。但是,死信队列是函数特定于版本的配置的一部分,因此在发布某个版本时锁定。失败时的目标还支持其他目标,并在调用记录中包含有关函数响应的详细信息。

如果您没有队列或主题,请创建一个队列或主题。选择与您的使用案例匹配的目标类型。

要将事件发送到队列或主题,您的函数需要其他权限。添加具有函数执行角色所需权限的策略。

如果已使用客户管理的密钥加密目标队列或主题,则执行角色也必须是密钥的基于资源的策略中的用户。

创建目标并更新函数的执行角色后,将死信队列添加到函数中。您可以配置多个函数,以便将事件发送到同一目标。

配置死信队列

  1. 打开 Lambda 控制台 函数页面

  2. 选择函数。

  3. Asynchronous invocation (异步调用) 下,选择 Edit (编辑)

  4. DLQ resource (DLQ 资源) 设置为 Amazon SQSAmazon SNS

  5. 选择目标队列或主题。

  6. 选择 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 跟踪相关联。

死信队列消息属性

  • RequestID(字符串)– 调用请求的 ID。请求 ID 显示在函数日志中。您还可以使用 X-Ray 开发工具包,在跟踪中的属性上记录请求 ID。然后,可以在 X-Ray 控制台中按请求 ID 搜索跟踪。有关示例,请参阅错误处理器示例

  • ErrorCode(数字)– HTTP 状态代码。

  • ErrorMessage(字符串)– 错误消息的第一个 1 KB 文本块。


      Amazon SQS 控制台中的死信队列事件属性。

如果 Lambda 无法向死信队列发送消息,则会删除该事件并发出 DeadLetterErrors 指标。之所以发生这种情况,可能是由于缺少权限,或者消息的总大小超过目标队列或主题的限制。例如,如果正文接近 256 KB 的 Amazon SNS 通知触发导致错误的功能,则 Amazon SNS 添加的附加事件数据与 Lambda 添加的属性相结合,可能会导致消息超过死信队列中允许的最大大小。

如果您正在使用 Amazon SQS 作为事件源,请在 Amazon SQS 队列本身而不是 Lambda 函数上配置死信队列。有关更多信息,请参阅将 AWS Lambda 与 Amazon SQS 结合使用