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

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

异步调用

多个 Amazon Web Services(如 Amazon Simple Storage Service(Amazon S3)和 Amazon Simple Notification Service(Amazon SNS)将异步调用函数以处理事件。在异步调用函数时,您不会等待函数代码的响应。您将事件交给 Lambda,Lambda 处理其余部分。您可以配置 Lambda 处理错误的方式,还可以将调用记录发送到下游资源,例如亚马逊简单队列服务 (Amazon SQS) Simple Queue Service 或 Ama EventBridge zon (),将EventBridge应用程序的组件链接在一起。

Lambda 如何处理异步调用

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


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

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

aws lambda invoke \ --function-name my-function \ --invocation-type Event \ --cli-binary-format raw-in-base64-out \ --payload '{ "key": "value" }' response.json

如果使用 cli-binary-format 版本 2,则 Amazon CLI 选项是必需的。要将其设为默认设置,请运行 aws configure set cli-binary-format raw-in-base64-out。有关更多信息,请参阅版本 2 的 Amazon Command Line Interface 用户指南中的 Amazon CLI 支持的全局命令行选项

{ "StatusCode": 202 }

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

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

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

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

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

您还可以配置 Lambda 以将调用记录发送至其他服务。Lambda 支持以下异步调用目标。请注意,不支持 SQS FIFO 队列和 SNS FIFO 主题。

  • Amazon SQS – 标准 SQS 队列。

  • Amazon SNS – 标准 SNS 主题。

  • Amazon Lambda – Lambda 函数。

  • 亚马逊 EventBridge — EventBridge 活动巴士。

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

如果 Lambda 无法将记录发送到您配置的目的地,它会向 Amazon 发送一个DestinationDeliveryFailures指标。 CloudWatch如果您的配置包含不支持的目标类型,例如 Amazon SQS FIFO 队列或 Amazon SNS FIFO 主题,则可能会发生这种情况。权限误配和大小限制可能会导致发生传输错误。有关 Lambda 调用指标的更多信息,请参阅 调用指标

注意

要防止触发函数,可以将函数的预留并发设置为零。当您将异步调用函数的预留并发设置为零时,Lambda 会开始将新事件发送到已配置的死信队列或失败时的事件目标,且不会做出任何重试。要处理在预留并发设置为零时发送的事件,您必须使用死信队列或失败时事件目标中的事件。

配置异步调用的错误处理

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

配置错误处理
  1. 打开 Lamba 控制台的 Functions(函数)页面。

  2. 选择函数。

  3. 选择 Configuration(配置),然后选择 Asynchronous invocation(异步调用)

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

  5. 配置以下设置。

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

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

  6. 选择保存

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

配置异步调用目标

要保留异步调用的记录,请向函数添加目标。您可以选择将成功或失败的调用发送到目标。每个函数可以有多个目标,因此您可以为成功和失败的事件配置不同的目标。发送到目标的每条记录都是一个 JSON 文档,其中包含有关调用的详细信息。与错误处理设置一样,您可以在函数版本或别名上配置目标。

注意

您还可以保留特定事件源映射类型的失败调用记录。有关更多信息,请参阅 为事件源映射调用配置目标

下表列出了 Lambda 支持的异步调用记录目标。要让 Lambda 成功将记录发送到您选择的目标,请确保函数的执行角色也包含相关权限。该表还描述了每种目标类型如何接收 JSON 调用记录。

目标类型 所需的权限 特定于目标的 JSON 格式

Amazon SQS 队列

sqs: SendMessage

Lambda 将调用记录作为 Message 传递到目标。

Amazon SNS 主题

sns:Publish

Lambda 将调用记录作为 Message 传递到目标。

Lambda 函数

InvokeFunction

Lambda 将调用记录作为有效负载传递给函数。

EventBridge

事件:PutEvents

  • Lambda 在调用detail中传递调用记录。 PutEvents

  • source 事件字段的值为 lambda

  • detail-type 事件字段的值为“Lambda Function Invocation Result – Success”(Lambda 函数调用结果 – 成功)或“Lambda Function Invocation Result – Failure”(Lambda 函数调用结果 – 失败)。

  • resource 事件字段包含函数和目标的 Amazon 资源名称(ARN)。

  • 有关其他事件字段,请参阅 Amazon EventBridge 事件

以下示例显示了由于函数错误而导致三次处理尝试失败的事件的调用记录。调用记录包含有关事件、响应和记录发送原因的详细信息。

{ "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" } }

以下步骤介绍如何使用 Lambda 控制台配置函数的目标。

为异步调用记录配置目标
  1. 打开 Lamba 控制台的 Functions(函数)页面。

  2. 选择函数。

  3. Function overview (函数概览) 下,选择 Add destination (添加目标)

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

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

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

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

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

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

  8. 选择 Save(保存)。

当调用与条件匹配时,Lambda 会向目标发送包含调用详细信息的 JSON 文档。

特定于目标的 JSON 格式
  • 对于 Amazon SQS 和 Amazon SNS(SnsDestinationSqsDestination),调用记录会作为 Message 传递到目标。

  • 对于 Lambda(LambdaDestination),调用记录会作为有效负载传递给函数。

  • 对于 EventBridge (EventBridgeDestination),调用记录作为PutEvents调用detail中的传递。source 事件字段的值为 lambdadetail-type 事件字段的值为 Lambda Function Invocation Result – Success(Lambda 函数调用结果 – 成功)或 Lambda Function Invocation Result – Failure(Lambda 函数调用结果 – 失败)。resource 事件字段包含函数和目标的 Amazon 资源名称(ARN)。有关其他事件字段,请参阅 Amazon EventBridge 事件

以下示例显示了由于函数错误而导致三次处理尝试失败的事件的调用记录。

例 调用记录
{ "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" } }

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

追踪发往目的地的请求

在每个请求排队、由 Lambda 函数处理并传递到目标服务时,您可以使用 Amazon X-Ray 查看每个请求的连接视图。当您为调用函数的函数或服务激活 X-Ray 跟踪时,Lambda 会向请求添加 X-Ray 标头并将标头传递给目标服务。来自上游服务的跟踪会自动链接到来自下游 Lambda 函数和目标服务的跟踪,从而创建整个 end-to-end 应用程序的视图。有关跟踪的更多信息,请参阅 配合使用 Amazon Lambda和 Amazon X-Ray

异步调用配置 API

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

要使用 Amazon 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" } } }

死信队列

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

要重新处理死信队列中的事件,您可以将其设置为 Lambda 函数的事件源。或者,您也可以手动检索事件。

您可以为死信队列选择 Amazon SQS 标准队列或 Amazon SNS 标准主题。不支持 FIFO 队列和 Amazon SNS FIFO 主题。如果您没有队列或主题,请创建一个队列或主题。选择与您的使用案例匹配的目标类型。

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

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

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

配置死信队列
  1. 打开 Lamba 控制台的 Functions(函数)页面。

  2. 选择函数。

  3. 选择 Configuration(配置),然后选择 Asynchronous invocation(异步调用)

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

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

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

  7. 选择保存

要通过 Amazon 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 按原样将事件发送到死信队列,并在属性中包含其他信息。您可以使用此信息来标识函数返回的错误,或者将事件与日志或 Amazon 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 函数上配置死信队列。有关更多信息,请参阅将 Lambda 与 Amazon SQS 结合使用