为基于单元的架构设置无服务器单元路由器 - AWS 规范指引

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

为基于单元的架构设置无服务器单元路由器

Mian Tariq 和 Ioannis Lioupras,Amazon Web Services

Summary

作为全球基于单元的应用程序系统的入口点,单元路由器负责将用户高效分配到相应的单元,并向用户提供端点。蜂窝路由器处理诸如存储 user-to-cell映射、监控信元容量和在需要时请求新信元之类的功能。在可能发生中断的情况下,维持单元路由器的功能至关重要。

此模式中的单元路由器设计框架聚焦于韧性、可扩展性及整体性能优化。该模式使用静态路由,即客户端在首次登录时缓存端点,之后直接与单元进行通信。这种解耦设计能在单元路由器出现故障时,确保基于单元的应用程序功能不中断,从而提升系统韧性。

此模式使用 AWS CloudFormation 模板来部署架构。有关模板部署的内容或使用部署相同配置的详细信息 AWS Management Console,请参阅 “其他信息” 部分。

重要

此模式中显示的演示、代码和 CloudFormation 模板仅用于解释目的。所提供的资料仅为阐释设计模式、帮助理解而准备。演示和代码尚未达到生产环境可用标准,不应用于任何实际生产活动。强烈不建议尝试在生产环境中使用该代码或演示,否则风险自负。建议在生产环境中实施此模式或其任何组件前,咨询专业人士并进行全面测试。

先决条件和限制

先决条件

产品版本

  • Python 3.12

架构

下图展示了单元路由器的高层级设计。

单元路由器的五步流程。

该图逐步展示了以下工作流:

  1. 用户与 Amazon API Gateway 建立连接,后者是单元路由器 API 端点的前端入口。

  2. Amazon Cognito 负责处理身份验证和授权操作。

  3. 该 AWS Step Functions 工作流程由以下组件组成:

    • Orchestrator AWS Step Functions − Orchestrator 用于创建工作流程或状态机。该工作流由单元路由器 API 触发。Orchestrator 根据资源路径执行 Lambda 函数。

    • DispatcherDispatcher Lambda 函数为每个新注册用户识别并分配一个静态单元。该函数会搜索用户数量最少的单元,将其分配给用户并返回端点。

    • 映射器-该Mapper操作处理由模板创建的 Amazon RoutingDB DynamoDB 数据库中的 user-to-cell映射。 CloudFormation 触发后,Mapper 函数会为已分配的用户提供其端点。

    • ScalerScaler 函数跟踪单元的占用情况和可用容量。需要时,Scaler 函数可通过 Amazon Simple Queue Service(Amazon SQS)向预调配和部署层发送请求,以请求创建新单元。

    • ValidatorValidator 函数验证单元端点的有效性,并检测任何潜在问题。

  4. RoutingDB存储单元信息和属性(API 端点 AWS 区域、状态、指标)。

  5. 当单元的可用容量超过阈值时,单元路由器会通过 Amazon SQS 请求预调配和部署服务以创建新单元。

新单元创建后,从预调配和部署层更新 RoutingDB。但此流程不在此模式的范围之内。如需了解基于单元的架构设计前提的概述,以及此模式中所使用单元路由器设计的详细信息,请参阅其他信息部分。

工具

AWS 服务

  • Amazon API Gateway 可帮助您创建、发布、维护、监控和保护任何规模的 RES WebSocket APIs T、HTTP。

  • AWS CloudFormation帮助您设置 AWS 资源,快速一致地配置资源,并在和的整个 AWS 账户 生命周期中对其进行管理 AWS 区域。

  • Amazon Cognito 为您的 Web 和移动应用程序提供身份验证、授权和用户管理。

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

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

  • Amazon Simple Storage Service(Amazon S3)是一项基于云的对象存储服务,可帮助您存储、保护和检索任意数量的数据。

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

  • AWS Step Functions是一项无服务器编排服务,可帮助您组合 Lambda 函数和其他函数 AWS 服务 来构建业务关键型应用程序。

其他工具

  • Python 是通用的计算机编程语言。

代码存储库

此模式的代码可在 GitHub Serverless-Cell- Router 存储库中找到。

最佳实践

有关构建基于单元的架构的最佳实践,请参阅以下 Well-Architected 指南 AWS :

操作说明

Task说明所需技能

克隆示例代码存储库。

要将 Serverless-Cell-Router GitHub 存储库克隆到您的计算机,请使用以下命令:

git clone https://github.com/aws-samples/Serverless-Cell-Router/
开发者版

设置 AWS CLI 临时证书。

使用您的 AWS CLI 凭据进行配置 AWS 账户。本演练使用 AWS IAM Identity Cen ter 命令行或编程访问选项提供的临时证书。这会将AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY、和AWS_SESSION_TOKEN AWS 环境变量设置为相应的凭据,以便与一起使用 AWS CLI。

开发者版

创建 S3 存储桶。

创建一个 S3 存储桶,用于存储和访问模板部署的 Serverless-Cell-Router Lambda 函数。 CloudFormation 要创建 S3 存储桶,请使用以下命令:

aws s3api create-bucket --bucket <bucket name> --region eu-central-1 --create-bucket-configuration LocationConstraint=eu-central-1
开发者版

创建 .zip 文件。

Functions 目录下的每个 Lambda 函数创建一个 .zip 文件。这些 .zip 文件将用于部署 Lambda 函数。在 Mac 系统上,可使用以下 zip 命令:

zip -j mapper-scr.zip Functions/Mapper.py zip -j dispatcher-scr.zip Functions/Dispatcher.py zip -j scaler-scr.zip Functions/Scaler.py zip -j cp validator-scr.zip Functions/Validator.py zip -j dynamodbDummyData-scr.zip Functions/DynamodbDummyData.py
开发者版

将 .zip 文件复制到 S3 存储桶。

要将所有 Lambda 函数 .zip 文件复制到 S3 存储桶,请使用以下命令:

aws s3 cp mapper-scr.zip s3://<bucket name> aws s3 cp dispatcher-scr.zip s3://<bucket name> aws s3 cp scaler-scr.zip s3://<bucket name> aws s3 cp validator-scr.zip s3://<bucket name> aws s3 cp dynamodbDummyData-scr.zip s3://<bucket name>
开发者版
Task说明所需技能

部署 CloudFormation 模板。

要部署 CloudFormation 模板,请运行以下 AWS CLI 命令:

aws cloudformation create-stack --stack-name serverless.cell-router \ --template-body file://Serverless-Cell-Router-Stack-v10.yaml \ --capabilities CAPABILITY_IAM \ --parameters ParameterKey=LambdaFunctionMapperS3KeyParameterSCR,ParameterValue=mapper-scr.zip \ ParameterKey=LambdaFunctionDispatcherS3KeyParameterSCR,ParameterValue=dispatcher-scr.zip \ ParameterKey=LambdaFunctionScalerS3KeyParameterSCR,ParameterValue=scaler-scr.zip \ ParameterKey=LambdaFunctionAddDynamoDBDummyItemsS3KeyParameterSCR,ParameterValue=dynamodbDummyData-scr.zip \ ParameterKey=LambdaFunctionsS3BucketParameterSCR,ParameterValue=<S3 bucket storing lambda zip files> \ ParameterKey=CognitoDomain,ParameterValue=<Cognito Domain Name> \ --region <enter your aws region id, e.g. "eu-central-1">
开发者版

查看进度。

登录 AWS Management Console,打开 CloudFormation 控制台 https://console.aws.amazon.com/cloudformation/,然后查看堆栈开发进度。当状态为时 CREATE_COMPLETE,表示堆栈已成功部署。

开发者版
Task说明所需技能

为用户分配单元。

要启动 Orchestrator,请运行以下 curl 命令:

curl -X POST \ -H "Authorization: Bearer {User id_token}" \ https://xxxxxx.execute-api.eu-central-1.amazonaws.com/Cell_Router_Development/cells

Orchestrator 会触发 Dispatcher 函数的执行。反过来,Dispatcher 会验证该用户是否存在。如果找到了用户,则会Dispatcher返回关联的单元 ID 和终端节点 URLs。如果未找到该用户,Dispatcher 会为用户分配一个单元,并将该单元 ID 发送至 Scaler 函数,以评估分配的单元的剩余容量。

Scaler 函数的响应如下:

"cellID : cell-0002 , endPoint_1 : https://xxxxx.execute-api.eu-north-1.amazonaws.com/ , endPoint_2 : https://xxxxxxx.execute-api.eu-central-1.amazonaws.com/"

开发者版

检索用户单元。

要使用 Orchestrator 执行 Mapper 函数,请运行以下命令:

curl -X POST \ -H "Authorization: Bearer {User id_token}" \ https://xxxxxxxxx.execute-api.eu-central-1.amazonaws.com/Cell_Router_Development/mapper

Orchestrator搜索分配给用户的单元格并返回单元格 ID,并在以下响应 URLs 中返回:

"cellID : cell-0002 , endPoint_1 : https://xxxxx.execute-api.eu-north-1.amazonaws.com/ , endPoint_2 : https://xxxxxxx.execute-api.eu-central-1.amazonaws.com/"

开发者版
Task说明所需技能

清除资源。

为避免您的账户产生额外费用,请执行以下操作:

  1. 清空您为 Lambda 函数创建的 S3 存储桶

  2. 删除 存储桶。

  3. 删除 CloudFormation 堆栈。

应用程序开发人员

相关资源

参考

视频

Physalia:基于单元的架构,旨在提升 Amazon EBS 的可用性

https://www.youtube-nocookie.com/embed/6Iknq?RZMFic 控件=0

附加信息

基于单元的架构设计前提

尽管此模式聚焦于单元路由器,但了解整个环境非常重要。该环境被构建为三个独立的层:

  • 路由层,也称为薄层,包含单元路由器

  • 单元层,由多个不同的单元组成

  • 配置和部署层,负责单元的预调配及应用程序的部署

即使存在影响其他层的损伤,每层也能维持其功能。 AWS 账户 用作故障隔离边界。

下图从高层级视角展示了这些层。单元层以及预调配和部署层不在此模式的范围之内。

路由层、包含多个单元账户的单元层,以及预调配和部署层。

有关基于单元的架构的更多信息,请参阅使用基于单元的架构缩小影响范围:单元路由

单元路由器设计模式

单元路由器是跨单元共享的组件。为了减轻潜在影响,路由层必须使用精简、水平可扩展且尽可能轻量化的设计。作为系统的入口点,路由层仅包含高效地将用户分配到相应单元所需的组件。该层内的组件不参与单元的管理或创建。

此模式使用静态路由,这意味着客户端在首次登录时缓存端点,之后直接与单元建立通信。客户端会定期与单元路由器交互,以确认当前状态或获取更新。这种刻意设计的解耦机制能在单元路由器停机时确保现有用户的操作不中断,从而为系统提供持续的功能支持与韧性。

在此模式中,单元路由器支持以下功能:

  • 从预调配和部署层的单元数据库中检索单元数据,并存储或更新本地数据库。

  • 使用单元分配算法为应用程序的每个新注册用户分配一个单元。

  • 将 user-to-cells映射存储在本地数据库中。

  • 在用户分配过程中检查单元的容量,并向预调配和部署层的资源自动分配机制发送事件以创建单元。

  • 使用单元创建标准算法来提供此功能。

  • 通过提供静态单元来响应新注册 URLs 的用户请求。这些 URLs 内容将在客户端上缓存,并附上生存时间 (TTL)。

  • 通过提供新的或更新的 URL 来响应现有用户针对无效 URL 的请求。

要进一步了解 CloudFormation 模板设置的演示蜂窝路由器,请查看以下组件和步骤:

  1. 设置并配置 Amazon Cognito 用户池。

  2. 为单元路由器设置和配置 API Gateway API。

  3. 创建 DynamoDB 表。

  4. 创建并配置 SQS 队列。

  5. 实施 Orchestrator

  6. 实现 Lambda 函数:DispatcherScalerMapperValidator

  7. 评估和验证。

此模式的前提假设是预调配和部署层已搭建完成。其实现细节超出了该构件的范围。

由于这些组件是通过 CloudFormation 模板设置和配置的,因此以下步骤将以描述性和高级的形式呈现。假设您具备完成设置和配置所需的 AWS 技能。

1。设置并配置 Amazon Cognito 用户池

登录并打开 Amazon Cognito 控制台,网址为。 AWS Management Consolehttps://console.aws.amazon.com/cognito/设置并配置名为 CellRouterPool 的 Amazon Cognito 用户池,配置内容需包含应用程序集成、托管 UI 以及所需权限。

2。为单元路由器设置和配置 API Gateway API

打开 API Gateway 控制台,网址为https://console.aws.amazon.com/apigateway/。设置并配置名为 CellRouter 的 API,该 API 需使用与 Amazon Cognito 用户池 CellRouterPool 集成的 Amazon Cognito 授权方。需实现以下元素:

  • CellRouter API 资源,包括 POST 方法

  • 与步骤 5 中实现的 Step Functions 工作流集成

  • 通过 Amazon Cognito 授权方进行授权

  • 集成请求和响应映射

  • 分配所需权限

3。创建 DynamoDB 表

在上打开 DynamoDB 控制台,然后使用https://console.aws.amazon.com/dynamodb/以下配置创建名为的标准 DynamoDB 表:tbl_router

  • 分区键marketId

  • 排序键cellId

  • 容量模式 ‒ 预调配

  • Point-in-time 恢复 (PITR)-关

索引选项卡上,创建名为 marketId-currentCapacity-index 的全局二级索引。Scaler Lambda 函数将使用索引高效搜索已分配用户数量最少的单元。

创建具有以下属性的表结构:

  • marketId ‒ 欧洲

  • cellId ‒ cell-0002

  • currentCapacity ‒ 2

  • endPoint_1− <第一个区域的端点>

  • endPoint_2− <第二个区域的端点>

  • IsHealthy ‒ True

  • maxCapacity ‒ 10

  • regionCode_1eu-north-1

  • regionCode_2eu-central-1

  • userIds ‒ <您的电子邮件地址>

4。创建并配置 SQS 队列

在上打开 Amazon SQS 控制台 https://console.aws.amazon.com/sqs/,然后创建一个名为 “CellProvisioning配置了亚马 SQS 密钥加密” 的标准 SQS 队列。

5。实现 Orchestrator

开发 Step Functions 工作流,作为路由器的 Orchestrator。该工作流可通过单元路由器 API 调用,并根据资源路径执行指定的 Lambda 函数。将该 Step 函数与单元路由器 CellRouter 的 API Gateway API 集成,并配置调用 Lambda 函数所需的权限。

图表显示了以下工作流。选择状态会调用某个 Lambda 函数。如果 Lambda 函数执行成功,则工作流结束。如果 Lambda 函数执行失败,则调用失败状态。

包含这四个函数且以失败状态结束的工作流示意图。

6。实现 Lambda 函数

实现 DispatcherMapperScalerValidator 函数。在演示环境中设置并配置每个函数时,需为函数定义一个角色,并为其分配对 DynamoDB 表 tbl_router 执行所需操作的必要权限。此外,需将每个函数集成到 Orchestrator 工作流中。

Dispatcher 函数

Dispatcher 函数负责为每个新注册的用户识别并分配一个静态单元。当新用户在全局应用程序中注册时,请求会发送至 Dispatcher 函数。该函数将使用预定义的评估标准来处理请求,例如:

  1. 区域 − 选择用户所在业务区域内的单元。例如,如果用户正在从欧洲访问全球应用程序,请选择 AWS 区域 在欧洲使用的单元格。

  2. 邻近性或延迟 – 选择距离用户最近的单元。例如,如果用户从荷兰访问应用程序,该函数会优先考虑使用法兰克福和爱尔兰区域的单元。“哪个单元最近”的判断依据是用户位置与单元所在区域之间的延迟等指标。对于此示例模式,相关信息由预调配和部署层以静态方式提供。

  3. 健康状态Dispatcher 函数会根据提供的单元状态(健康状态 = true 或 false),检查所选单元是否处于健康状态。

  4. 容量 − 用户分配基于单元用户数量最少逻辑,因此用户会被分配到用户数量最少的单元。

注意

上述标准仅用于解释此示例模式。在实际的单元路由器实现中,您可以根据具体使用案例定义更精细、更贴合业务场景的评估标准。

Orchestrator 调用 Dispatcher 函数将用户分配到单元。在此演示函数中,业务区域值是一个静态参数,定义为 europe

Dispatcher 函数会评估该用户是否已分配单元。如已分配单元,则 Dispatcher 函数将返回该单元的端点。如果没有为该用户分配任何单元,该函数会搜索用户数量最少的单元,将其分配给用户并返回端点。通过使用全局二级索引,单元搜索查询的效率得到了优化。

Mapper 函数

Mapper函数负责监督数据库中 user-to-cell映射的存储和维护。每个注册用户仅分配一个单元,每个单元都有两个不同的单元 URLs ——每个 AWS 区域各一个。这些端点充当托管在 API Gateway 上的 API 端点, URLs 充当全球应用程序的入站点。

当该Mapper函数收到来自客户端应用程序的请求时,它会对 DynamoDB tbl_router 表运行查询,以检索 user-to-cell与提供的电子邮件 ID 关联的映射。如果它找到了分配的单元格,则该Mapper函数会立即提供该单元格的两个单元格 URLs。该Mapper功能还会主动监控单元的更改 URLs,并启动通知或更新用户设置。

Scaler 函数

Scaler 函数管理单元的剩余容量。对于每个新用户注册请求,Scaler 函数会评估 Dispatcher 函数为该用户分配的单元的可用容量:如果根据指定的评估标准判断该单元已达到预先确定的容量上限,则该函数会通过 Amazon SQS 队列向预调配和部署层发起请求,请求预调配并部署新的单元。例如,可根据以下一组评估标准来执行单元的扩展:

  1. 最大用户数 − 每个单元最多可承载 500 名用户。

  2. 缓冲容量 − 每个单元的缓冲容量为 20%,这意味着每个单元可随时分配给 400 名用户。剩余 20% 的缓冲容量预留用于未来使用案例以及应对意外情况(例如,单元创建与预调配服务不可用时)。

  3. 单元创建 ‒ 当现有单元的容量利用率达到 70% 时,会立即触发创建额外单元的请求。

注意

上述标准仅用于解释此示例模式。在实际的单元路由器实现中,您可以根据具体使用案例定义更精细、更贴合业务场景的评估标准。

Dispatcher 成功为新注册的用户分配单元后,Orchestrator 会执行演示版 Scaler 代码。ScalerDispatcher 收到单元 ID 后,会根据预定义的评估标准判断该指定单元是否有足够的容量容纳更多用户。如果单元的容量不足,Scaler 函数会向 Amazon SQS 服务发送一条消息。预调配和部署层中的服务会获取该消息,并启动新单元的预调配流程。

Validator 函数

Validator 函数可识别并解决与单元访问相关的问题。当用户登录全局应用程序时,该应用程序会 URLs 从用户配置文件设置中检索单元格,并将用户请求路由到单元内两个分配的区域之一。如果无法访问, URLs 则应用程序可以向蜂窝路由器发送验证 URL 请求。此时,单元路由器 Orchestrator 会调用 ValidatorValidator 启动验证流程。验证流程可能包含(但不限于)以下检查:

  • 将请求 URLs 中的单元格与 URLs 存储在数据库中的单元格进行交叉引用,以识别和处理潜在的更新

  • 执行深度运行状况检查(例如,向单元端点发送 HTTP GET 请求)

总之,Validator 函数会响应客户端应用程序请求,返回验证状态以及所需的任何补救步骤。

Validator 旨在增强用户体验。假设这样的场景,即某些用户在访问全局应用程序时遇到困难,因为事件导致单元暂时不可用。Validator 函数可提供指导性的补救步骤,而不仅仅是显示一般错误。这些步骤可能包括以下操作:

  • 告知用户有关事件的信息。

  • 提供服务恢复前的大致等待时间。

  • 提供支持联系电话,以便用户获取更多信息。

Validator函数的演示代码验证请求中用户提供的单元格是否与表 URLs 中存储的记录相匹配。tbl_routerValidator 函数还会检查这些单元是否处于健康状态。