

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

# 使用 Amazon API Gateway 和 AWS Lambda 异步处理事件
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda"></a>

*Andrea Meroni、Mariem Kthiri、Nadim Majed 和 Michael Wallner，Amazon Web Services*

## Summary
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-summary"></a>

[Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html) 是一项完全托管的服务，开发人员可以使用它来创建、发布、维护、监控和保护 APIs 任何规模。它可以处理涉及接受和处理多达几十万个并发 API 调用的所有任务。

集成超时是 API Gateway 的一个重要服务配额。超时是指后端服务必须返回响应的最大时限，超过该时限后，REST API 将返回错误。对于同步工作负载而言，29 秒的硬性限制通常是可以接受的。但是，对于想要将 API Gateway 用于异步工作负载的开发人员来说，这个限制是挑战。

此模式显示了使用 API Gateway 和 AWS Lambda异步处理事件的架构示例。这个架构支持运行时长不超过 15 分钟的处理作业，并使用基本的 REST API 作为接口。

[Projen](https://pypi.org/project/projen/) [与 T [AWS Cloud Development Kit (AWS CDK) oo](https://docs.aws.amazon.com/cdk/v2/guide/cli.html) lkit、[Docker](https://docs.docker.com/get-docker/) 和 Node.js 结合使用 AWS 账户，用于设置本地开发环境并将示例架构部署到目标。](https://nodejs.org/en/download/)Projen 会自动创建一个 [Python](https://www.python.org/downloads/) 虚拟环境，其中包含[预提交](https://pre-commit.com/)工具以及用于代码质量保证、安全扫描和单元测试的工具。有关更多信息，请参阅[工具](#process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-tools)部分。

## 先决条件和限制
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-prereqs"></a>

**先决条件**
+ 活跃的 AWS 账户
+ 您的工作站上已安装以下工具：
  + [AWS Cloud Development Kit (AWS CDK) 工具包](https://docs.aws.amazon.com/cdk/v2/guide/cli.html)版本 2.85.0
  + [Docker](https://docs.docker.com/get-docker/) 版本 20.10.21
  + [Node.js](https://nodejs.org/en/download/) 版本 18.13.0
  + [Projen](https://pypi.org/project/projen/) 版本 0.71.111
  + [Python](https://www.python.org/downloads/) 版本 3.9.16

**限制**
+ 作业的运行时上限受限于 Lambda 函数的运行时上限（15 分钟）。
+ 并发作业请求的最大数受 Lambda 函数预留并发数的限制。

## 架构
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-architecture"></a>

下图显示了任务 API 与事件处理和错误处理 Lambda 函数以及存储在 Amazon 事件档案中的事件之间的交互。 EventBridge 

![](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/e027130c-44c1-41ab-bbe9-f196a49bd9ac/images/3c437b65-48e3-477d-aeea-6ff938cc3285.png)


典型的工作流程包含以下步骤：

1. 您通过 AWS Identity and Access Management (IAM) 进行身份验证并获取安全证书。

1. 您将 HTTP `POST` 请求发送到 `/jobs` 作业 API 端点，并在请求正文中指定作业参数。

1. 作业 API（API Gateway REST API）返回一个包含作业标识符的 HTTP 响应。

1. 作业 API 异步调用事件处理 Lambda 函数。

1. 事件处理函数处理事件，然后将作业结果放入作业 Amazon DynamoDB 表中

1. 您通过第 3 步中的作业标识符 `{jobId}`，向 `/jobs/{jobId}` 作业 API 端点发送 HTTP `GET` 请求。

1. 作业 API 查询 `jobs` DynamoDB 表以检索作业结果。

1. 作业 API 返回包含作业结果的 HTTP 响应。

1. 事件处理函数将事件发送到错误处理函数（若事件处理失败）。

1. 错误处理函数将作业参数放入 `jobs` DynamoDB 表中。

1. 您可以向 `/jobs/{jobId}` 作业 API 端点发送 HTTP `GET` 请求，检索作业参数。

1. 如果错误处理失败，则错误处理函数会将事件发送到 EventBridge 事件存档。

   您可以使用重播存档的事件 EventBridge。

## 工具
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-tools"></a>

**AWS 服务**
+ [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html)是一个软件开发框架，可帮助您在代码中定义和配置 AWS Cloud 基础架构。
+ [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 是一个开源工具，可帮助您通过命令行外壳中的命令与 AWS 服务进行交互。
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) 是一项完全托管式 NoSQL 数据库服务，可提供快速、可预测、可扩展的性能。
+ [Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) 是一项无服务器事件总线服务，可帮助您将应用程序与来自各种来源的实时数据连接起来。例如，Lambda 函数、使用 API 目标的 HTTP 调用端点，或者其他 AWS 账户中的事件总线。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) 是一项计算服务，可帮助您运行代码，无需预调配或管理服务器。它只在需要时运行您的代码，并自动进行扩展，因此您只需为使用的计算时间付费。

**其他工具**
+ [autopep8](https://github.com/hhatto/autopep8) 会根据 Python 增强提案（PEP）8 风格指南自动格式化 Python 代码。
+ [Bandit](https://bandit.readthedocs.io/en/latest/) 会扫描 Python 代码，查找常见的安全问题。
+ [Commitizen](https://commitizen-tools.github.io/commitizen/) 是 Git 提交检查器和 `CHANGELOG` 生成器。
+ [cfn-lint 是个傻瓜](https://github.com/aws-cloudformation/cfn-lint) AWS CloudFormation 
+ [Checkov](https://github.com/bridgecrewio/checkov) 是一款静态代码分析工具，用于检查基础设施即代码（IaC）是否存在安全性和合规性配置错误。
+ [jq](https://stedolan.github.io/jq/download/) 是一个用于解析 JSON 的命令行工具。
+ [Postman](https://www.postman.com/) 是 API 平台。
+ [pre-commit](https://pre-commit.com/) 是 Git 挂钩管理器。
+ [Projen](https://github.com/projen/projen) 是项目生成器。
+ [pytest](https://docs.pytest.org/en/7.2.x/index.html) 是一个 Python 框架，用于编写可读的小型测试。

**代码存储库**

此示例架构代码可以在使用 [API Gateway 和 Lambda 进行 GitHub 异步事件处理](https://github.com/aws-samples/asynchronous-event-processing-api-gateway-lambda-cdk)存储库中找到。

## 最佳实践
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-best-practices"></a>
+ 此示例架构不包括对已部署基础设施的监控。如果您的使用案例需要监控，请评估添加 [CDK 监控构造](https://constructs.dev/packages/cdk-monitoring-constructs)或其他监控解决方案。
+ 此示例架构使用 [IAM 权限](https://docs.aws.amazon.com/apigateway/latest/developerguide/permissions.html)来控制对作业 API 的访问权限。任何被授权接管 `JobsAPIInvokeRole` 的人员皆可调用作业 API。因此，访问控制机制是二进制的。如果您的使用案例需要更复杂的授权模型，请使用不同的[访问控制机制](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-to-api.html)进行评估。
+ 当用户向 `/jobs` 作业 API 端点发送 HTTP `POST` 请求时，系统将在两个不同的层级验证输入数据：
  + Amazon API Gateway 负责执行第一个[请求的验证](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-method-request-validation.html)。
  + 事件处理函数执行第二个请求。

    当用户向 `/jobs/{jobId}` 作业 API 端点发出 HTTP `GET` 请求时，不会执行任何验证。如果您的使用案例需要额外的输入验证和更高的安全级别，请评估如何[使用 AWS WAF 来保护您的 API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html)。

## 操作说明
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-epics"></a>

### 设置环境
<a name="set-up-the-environment"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 克隆存储库。 | 要在本地克隆存储库，请运行以下命令：<pre>git clone https://github.com/aws-samples/asynchronous-event-processing-api-gateway-lambda-cdk.git</pre> | DevOps 工程师 | 
| 设置项目。 | 将目录更改为存储库根目录，然后使用 [Projen](https://github.com/projen/projen) 设置 Python 虚拟环境和所有工具：<pre>cd asynchronous-event-processing-api-gateway-api-gateway-lambda-cdk<br />npx projen</pre> | DevOps 工程师 | 
| 安装预提交挂钩。 | 要安装预提交挂钩，请执行以下操作：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda.html) | DevOps 工程师 | 

### 部署示例架构
<a name="deploy-the-example-architecture"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| Bootstrap AWS CDK。 | 要 AWS CDK 在中进行引导 AWS 账户，请运行以下命令：<pre>AWS_PROFILE=$YOUR_AWS_PROFILE npx projen bootstrap</pre> | AWS DevOps | 
| 部署示例架构。 | 要在中部署示例架构 AWS 账户，请运行以下命令：<pre>AWS_PROFILE=$YOUR_AWS_PROFILE npx projen deploy</pre> | AWS DevOps | 

### 测试架构
<a name="test-the-architecture"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 安装测试先决条件。 | 在您的工作站上安装（[AWS Command Line InterfaceAWS CLI）](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)、[Postman](https://www.postman.com/downloads/) 和 [jq](https://jqlang.github.io/jq/)。<br />建议使用 [Postman](https://www.postman.com/downloads/) 测试此示例架构，但这不是强制性的。如果选择其他 API 测试工具，请确保其支持 [AWS 签名版本 4 身份验证](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)，并参考可通过[导出 REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html) 检查的公开 API 端点。 | DevOps 工程师 | 
| 承担 `JobsAPIInvokeRole`。 | [承担](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sts/assume-role.html)部署命令输出中打印的 `JobsAPIInvokeRole`：<pre>CREDENTIALS=$(AWS_PROFILE=$<YOUR_AWS_PROFILE> aws sts assume-role \<br />--no-cli-pager \<br />--role-arn $<JOBS_API_INVOKE_ROLE_ARN> \<br />--role-session-name JobsAPIInvoke)<br />export AWS_ACCESS_KEY_ID=$(cat $CREDENTIALS | jq ‘.Credentials’’.AccessKeyId’)<br />export AWS_SECRET_ACCESS_KEY=$(cat $CREDENTIALS | jq ‘.Credentials’’.SecretAccessKey’)<br />export AWS_SESSION_TOKEN==$(cat $CREDENTIALS | jq ‘.Credentials’’.SessionToken’)</pre> | AWS DevOps | 
| 配置 Postman。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda.html) | AWS DevOps | 
| 测试示例架构。 | 要测试示例架构，请向作业 API [发送请求](https://learning.postman.com/docs/sending-requests/requests/#next-steps)。有关更多信息，请参阅 [Postman 文档](https://learning.postman.com/docs/getting-started/first-steps/sending-the-first-request/#send-an-api-request)。 | DevOps 工程师 | 

## 问题排查
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-troubleshooting"></a>


| 问题 | 解决方案 | 
| --- | --- | 
| 由于 [Amazon Lo CloudWatch gs 日志组](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html)`/aws/apigateway/JobsAPIAccessLogs`已经存在，因此销毁和随后重新部署示例架构会失败。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda.html) | 

## 相关资源
<a name="process-events-asynchronously-with-amazon-api-gateway-and-aws-lambda-resources"></a>
+ [API Gateway 映射模板和访问日志变量参考](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html)
+ [设置后端 Lambda 函数的异步调用](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-integration-async.html)