使用 Amazon API Gateway、Amazon SQS 和 AWS Fargate 异步处理事件 - AWS 规范指引

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

使用 Amazon API Gateway、Amazon SQS 和 AWS Fargate 异步处理事件

Andrea Meroni、Mariem Kthiri、Nadim Majed、Alessandro Trisolini 和 Michael Wallner,Amazon Web Services

Summary

Amazon API Gateway 是一项完全托管的服务,开发人员可以使用它来创建、发布、维护、监控和保护 APIs 任何规模。它可以处理涉及接受和处理多达几十万个并发 API 调用的所有任务。

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

此模式显示了使用 API Gateway、Amazon Simple Queue Service 和(亚马逊 SQS)异步处理事件的架构示例。 AWS Fargate这个架构支持运行无持续时间限制的处理作业,并使用基本的 REST API 作为接口。

Projen 与、Docker 和 Node.js 结合使用 AWS 账户,用于设置本地开发环境并将示例架构部署到目标。AWS Cloud Development Kit (AWS CDK)Projen 会自动创建一个 Python 虚拟环境,其中包含预提交工具以及用于代码质量保证、安全扫描和单元测试的工具。有关更多信息,请参阅工具部分。

先决条件和限制

先决条件

限制

  • 并发作业每分钟最多可处理 500 个任务,这是 Fargate 能够预调配的任务最大数。

架构

下图显示了作业 API 与 jobs Amazon DynamoDB 表、事件处理 Fargate 服务和错误处理函数的交互。 AWS Lambda 事件存储在 Amazon EventBridge 事件档案中。

架构图,后附描述。

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

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

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

  3. 作业 API(API Gateway REST API)返回一个包含作业标识符的 HTTP 响应。

  4. 作业 API 将消息 SQS 队列发送到 SQS 队列的消息。

  5. Fargate 从 SQS 队列提取消息、处理事件,然后将作业结果放入 jobs DynamoDB 表中。

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

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

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

  9. 如果事件处理失败,SQS 队列将事件发送到死信队列(DLQ)。

  10. EventBridge 事件启动错误处理函数。

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

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

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

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

工具

AWS 服务

  • AWS Cloud Development Kit (AWS CDK)是一个软件开发框架,可帮助您在代码中定义和配置 AWS Cloud 基础架构。

  • Amazon DynamoDB 是一项完全托管式 NoSQL 数据库服务,可提供快速、可预测、可扩展的性能。

  • AWS Fargate无需管理服务器或亚马逊弹性计算云 (Amazon EC2) 实例,即可帮助您运行容器。它与 Amazon Elastic Container Service(Amazon ECS)配合使用。

  • Amazon EventBridge 是一项无服务器事件总线服务,可帮助您将应用程序与来自各种来源的实时数据连接起来。例如,Lambda 函数、使用 API 目标的 HTTP 调用端点,或者其他 AWS 账户中的事件总线。

  • AWS Lambda 是一项计算服务,可帮助您运行代码,无需预调配或管理服务器。它只在需要时运行您的代码,并自动进行扩展,因此您只需为使用的计算时间付费。

  • Amazon Simple Queue Service (Amazon SQS) 提供了一个安全、持久且可用的托管队列,它可帮助您集成和分离分布式软件系统与组件。

其他工具

  • autopep8 会根据 Python 增强提案(PEP)8 风格指南自动格式化 Python 代码。

  • Bandit 会扫描 Python 代码,查找常见的安全问题。

  • Commitizen 是 Git 提交检查器和 CHANGELOG 生成器。

  • cfn-lint 是个傻瓜 AWS CloudFormation

  • Checkov 是一款静态代码分析工具,用于检查基础设施即代码(IaC)是否存在安全性和合规性配置错误。

  • jq 是一个用于解析 JSON 的命令行工具。

  • Postman 是 API 平台。

  • pre-commit 是 Git 挂钩管理器。

  • Projen 是项目生成器。

  • pytest 是一个 Python 框架,用于编写可读的小型测试。

代码存储库

此示例架构代码可以在使用 API Gateway 和 SQS 进行 GitHub 异步处理存储库中找到。

最佳实践

  • 此示例架构不包括对已部署基础设施的监控。如果您的使用案例需要监控,请评估添加 CDK 监控构造或其他监控解决方案。

  • 此示例架构使用 IAM 权限来控制对作业 API 的访问权限。任何被授权接管 JobsAPIInvokeRole 的人员皆可调用作业 API。因此,访问控制机制是二进制的。如果您的使用案例需要更复杂的授权模型,请使用不同的访问控制机制进行评估。

  • 当用户向 /jobs 作业 API 端点发送 HTTP POST 请求时,系统将在两个不同的层级验证输入数据:

    • API Gateway 负责执行第一个请求的验证

    • 事件处理函数执行第二个请求。

      当用户向 /jobs/{jobId} 作业 API 端点发出 HTTP GET 请求时,不会执行任何验证。如果您的用例需要额外的输入验证和更高的安全级别,请评估使用 AWS WAF 来保护您的 API

操作说明

Task说明所需技能

克隆存储库。

要在本地克隆存储库,请运行以下命令:

git clone https://github.com/aws-samples/asynchronous-event-processing-api-gateway-sqs-cdk.git
DevOps 工程师

设置项目。

将目录更改为存储库根目录,然后使用 Projen 设置 Python 虚拟环境和所有工具:

cd asynchronous-event-processing-api-gateway-api-gateway-sqs-cdk npx projen
DevOps 工程师

安装预提交挂钩。

要安装预提交挂钩,请执行以下操作:

  1. 激活 Python 虚拟环境

    source .env/bin/activate
  2. 安装预提交挂钩。

    pre-commit install pre-commit install --hook-type commit-msg
DevOps 工程师
Task说明所需技能

Bootstrap AWS CDK。

AWS CDK在中进行引导 AWS 账户,请运行以下命令:

AWS_PROFILE=$YOUR_AWS_PROFILE npx projen bootstrap
AWS DevOps

部署示例架构。

要在中部署示例架构 AWS 账户,请运行以下命令:

AWS_PROFILE=$YOUR_AWS_PROFILE npx projen deploy
AWS DevOps
Task说明所需技能

安装测试先决条件。

在您的工作站上安装(AWS Command Line InterfaceAWS CLI)Postmanjq

建议使用 Postman 测试此示例架构,但这不是强制性的。如果选择其他 API 测试工具,请确保其支持 AWS 签名版本 4 身份验证,并参考可通过导出 REST API 检查的公开 API 端点。

DevOps 工程师

承担 JobsAPIInvokeRole

承担 deploy 命令输出中打印的 JobsAPIInvokeRole

CREDENTIALS=$(AWS_PROFILE=$<YOUR_AWS_PROFILE> aws sts assume-role \ --no-cli-pager \ --role-arn $<JOBS_API_INVOKE_ROLE_ARN> \ --role-session-name JobsAPIInvoke) export AWS_ACCESS_KEY_ID=$(cat $CREDENTIALS | jq ‘.Credentials’’.AccessKeyId’) export AWS_SECRET_ACCESS_KEY=$(cat $CREDENTIALS | jq ‘.Credentials’’.SecretAccessKey’) export AWS_SESSION_TOKEN==$(cat $CREDENTIALS | jq ‘.Credentials’’.SessionToken’)
AWS DevOps

配置 Postman。

  • 要导入存储库中包含的 Postman 集合,请按照 Postman 文档中的说明操作。

  • 使用以下值设置 JobsAPI 变量

    • accessKeyassume-role 命令中 Credentials.AccessKeyId 属性的值。

    • baseUrldeploy 命令中 JobsApiJobsAPIEndpoint 输出的值,不带尾部斜杠。

    • region− 示例架构的部署 AWS 区域 位置的价值。

    • seconds ‒ 作业示例的输入参数值。必须为正整数。

    • secretKeyassume-role 命令中 Credentials.SecretAccessKey 属性的值。

    • sessionTokenassume-role 命令中 Credentials.SessionToken 属性的值。

AWS DevOps

测试示例架构。

要测试示例架构,请向作业 API 发送请求。有关更多信息,请参阅 Postman 文档

DevOps 工程师

问题排查

问题解决方案

由于 Amazon Lo CloudWatch gs 日志组/aws/apigateway/JobsAPIAccessLogs已经存在,因此销毁和随后重新部署示例架构会失败。

  1. 如有必要,请将日志数据导出至 Amazon Simple Storage Service(Amazon S3)

  2. 删除 CloudWatch 日志日志组/aws/apigateway/JobsAPIAccessLogs

  3. 重新部署示例架构。

由于CloudWatch 日志日志组/aws/ecs/EventProcessingServiceLogs已经存在,因此销毁和随后重新部署示例架构会失败。

  1. 如有必要,请将您的日志数据导出到 Amazon S3

  2. 删除 CloudWatch 日志日志组 /aws/ecs/EventProcessingServiceLogs.

  3. 重新部署示例架构。

相关资源