

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

# 使用 CQRS 和事件溯源将整体分解为微服务
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing"></a>

*Rodolfo Jr. Cerrada、Dmitry Gulin 和 Tabby Ward，Amazon Web Services*

## Summary
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-summary"></a>

此示例介绍了两种模式，使用命令查询责任分离 (CQRS) 模式和事件溯源模式。CQRS 模式将命令模型和查询模型职责分开。事件溯源模式利用异步事件驱动通信来改善整体用户体验。

您可使用 CQRS 和 Amazon Web Services (AWS) 服务独立维护和扩展每个数据模型，同时将您的整体应用程序重构为微服务架构。然后，您可使用事件溯源模式，将数据从命令数据库同步至查询数据库。

此示例使用包含解决方案 (\$1.sln) 文件的示例代码，您可以使用最新版本 Visual Studio 打开该文件。此示例包含奖励 API 代码，用于展示 CQRS 和事件溯源在 AWS 无服务器和传统或本地应用程序中的工作方式。

要了解有关 CQRS 和事件溯源的更多信息，请参阅[其他信息](#decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional)部分。

## 先决条件和限制
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-prereqs"></a>

**先决条件**
+ 一个活跃的 AWS 账户
+ Amazon CloudWatch
+ Amazon DynamoDB 表
+ Amazon DynamoDB Streams
+ AWS Identity and Access Management (IAM) 访问密钥。有关更多信息，请参阅*相关资源*部分中的视频
+ AWS Lambda
+ 熟悉 Visual Studio
+ 熟悉 AWS Toolkit for Visual Studio；有关更多信息，请参阅*相关资源*部分的*AWS Toolkit for Visual Studio 演示*

**产品版本**
+ [Visual Studio 2019 Community Edition](https://visualstudio.microsoft.com/downloads/)。
+ [AWS Toolkit for Visual Studio 2019](https://aws.amazon.com/visualstudio/)。
+ .NET Core 3.1。此组件是 Visual Studio 安装选项之一。若要在安装过程中纳入 .NET Core，请选择 **NET Core 跨平台开发**。

**限制**
+ 传统本地应用程序 (ASP.NET Core Web API 和数据访问对象) 的示例代码不附带数据库。但是，它附带了 `CustomerData` 内存对象，该对象充当模拟数据库。所提供的代码适用于测试模式。

## 架构
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-architecture"></a>

**源技术堆栈**
+ ASP.NET Core Web API 项目
+ IIS Web 服务器
+ 数据访问对象
+ CRUD 模型

**源架构**

在源架构中，CRUD 模型在一个应用程序中同时包含命令与查询接口。有关示例代码，请参阅 `CustomerDAO.cs`（附后）。

![\[应用程序、服务接口、客户 CRUD 模型以及数据库之间的连接。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/1cd3a84c-12c7-4306-99aa-23f2c53d3cd3.png)


**目标技术堆栈**
+ Amazon DynamoDB
+ Amazon DynamoDB Streams
+ AWS Lambda
+ （可选）Amazon API Gateway
+ （可选）Amazon Simple Notiﬁcation Service (Amazon SNS)

**目标架构**

在目标架构中，命令与查询接口是分开的。下图所示的架构可使用 API Gateway 和 Amazon SNS 进行扩展。有关更多信息，请参阅[其他信息](#decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional)部分。

![\[与无服务器客户命令和客户查询微服务连接的应用程序。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/1c665697-e3ac-4ef4-98d0-86c2cbf164c1.png)


1. 命令 Lambda 函数对数据库执行写入操作，如创建、更新或删除。

1. 查询 Lambda 函数对数据库执行读取操作，如获取或选择。

1. 此 Lambda 函数处理来自命令数据库的 DynamoDB 数据流，并更新查询数据库以获取更改。

## 工具
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-tools"></a>

**工具**
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) – Amazon DynamoDB 是一种全托管 NoSQL 数据库服务，提供快速而可预测的性能，能够实现无缝扩展。
+ [Amazon DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html) - DynamoDB Streams 捕获在任何 DynamoDB Streams 表中按时间排序的项目级修改序列。它还会将这类信息存储在日志中长达 24 个小时。静态加密会加密 DynamoDB 流中的数据。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) – AWS Lambda 是一项计算服务，支持无需预置或管理服务器即可运行代码。只有在需要时 Lambda 才运行您的代码，并且能自动扩缩，从每天几个请求扩展到每秒数千个请求。您只需为消耗的计算时间付费 - 代码未运行时不产生费用。
+ [AWS 管理控制台](https://docs.aws.amazon.com/awsconsolehelpdocs/latest/gsg/learn-whats-new.html) — AWS 管理控制台是一款 Web 应用程序，包含多种用于管理 Amazon Web Services 的服务控制台。
+ [Visual Studio 2019 Community Edition](https://visualstudio.microsoft.com/downloads/) – Visual Studio 2019 是一个集成式开发环境（IDE）。开源参与者可免费使用社区版。在此示例中，您将使用 Visual Studio 2019 Community Edition 打开、编译和运行示例代码。仅供查看，您可以使用任何文本编辑器或 [Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html)。
+ [AWS Toolkit for Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html) – AWS Toolkit for Visual Studio 是 Visual Studio IDE 的一个插件。AWS Toolkit for Visual Studio 可让您更轻松地开发、调试和部署使用 Amazon Web Services .NET 应用程序。

**代码**

示例代码附后。有关部署示例代码的说明，请参阅*操作*部分。

## 操作说明
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-epics"></a>

### 打开和生成解决方案
<a name="open-and-build-the-solution"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 打开解决方案。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发人员 | 
| 构建解决方案。 | 打开解决方案的上下文（右键单击）菜单，然后选择**生成解决方案**。这将生成和编译解决方案的所有项目。它应该可成功编译。Visual Studio 解决方案资源管理器应该显示目录结构。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发人员 | 

### 构建 DynamoDB 表格
<a name="build-the-dynamodb-tables"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 提供凭证。 | 如果您还没有访问密钥，请查看*相关资源*部分中的视频。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发人员、数据工程师、数据库管理员 | 
| 构建 项目。 | 要生成项目，请打开 **AwS.APG.CQRSES.Build** 项目的上下文（右键单击）菜单，然后选择**生成**。 | 应用程序开发人员、数据工程师、数据库管理员 | 
| 生成和填充表格。 | 若要生成表格并向其中填充种子数据，打开 **AwS.APG.CQRSES.Build** 项目的上下文（右键点击）菜单，然后选择**调试**、**启动新实例**。 | 应用程序开发人员、数据工程师、数据库管理员 | 
| 验证表结构与数据。 | 若要进行验证，请导航至 **AWS 各区服务浏览器**，然后展开 **Amazon DynamoDB**。它应该显示此表格。打开每个表，以显示示例数据。 | 应用程序开发人员、数据工程师、数据库管理员 | 

### 运行本地测试
<a name="run-local-tests"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 构建 CQRS 项目。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发人员、测试工程师 | 
| 生成事件溯源项目。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发人员、测试工程师 | 
| 运行测试。 | 要运行所有测试，请选择**查看**、**测试资源管理器**，然后选择**在视图中运行所有测试**。所有测试都应通过，通过后以绿色复选标记图标表示。  | 应用程序开发人员、测试工程师 | 

### 将 CQRS Lambda 函数发布至 AWS
<a name="publish-the-cqrs-lambda-functions-to-aws"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 发布第一个 Lambda 函数。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发者、 DevOps 工程师 | 
| 验证函数上传情况。 | （可选）您可以通过导航到 AWS 各区服务浏览器并展开 **AWS Lambda** 来验证函数是否已成功加载。若要打开测试窗口，请选择 Lambda 函数（双击）。 | 应用程序开发者、 DevOps 工程师 | 
| 测试 Lambda 函数。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html)所有 CQRS Lambda 项目都位于 ` CQRS AWS Serverless\CQRS\Command Microservice` 和 `CQRS AWS Serverless\CQRS\Command Microservice` 解决方案文件夹下。有关解决方案目录和项目，请参阅[其他信息](#decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional)部分中的**源代码目录**。 | 应用程序开发者、 DevOps 工程师 | 
| 发布其余函数。 | 对以下项目重复之前的步骤：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发者、 DevOps 工程师 | 

### 将 Lambda 函数设置为事件侦听器
<a name="set-up-the-lambda-function-as-an-event-listener"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 发布客户和奖励 Lambda 事件的处理程序。 | 若要发布每个事件处理程序，请按前述操作中的步骤进行操作。这些项目位于 `CQRS AWS Serverless\Event Source\Customer Event` 和 `CQRS AWS Serverless\Event Source\Reward Event` 解决方案文件夹下。有关更多信息，请参阅[其他信息](#decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional)中的*源代码目录*部分。 | 应用程序开发人员 | 
| 附加事件溯源 Lambda 事件侦听器。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html)侦听器成功连接至 DynamoDB 表后，它将显示在 Lambda 设计器页面上。 | 应用程序开发人员 | 
| 发布并附加 EventSourceReward Lambda 函数。 | **要发布并附加 `EventSourceReward` Lambda 函数，请重复前两个故事中的步骤，**cqrses-reward-cmd**从 DynamoDB 表下拉列表中进行选择。** | 应用程序开发人员 | 

### 测试和验证 DynamoDB 流与 Lambda 触发器
<a name="test-and-validate-the-dynamodb-streams-and-lambda-trigger"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 测试流数据和 Lambda 触发器。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发人员 | 
| 使用 DynamodDB 奖励查询表验证。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发人员 | 
| 使用 CloudWatch 日志进行验证。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | 应用程序开发人员 | 
| 验证 EventSourceCustomer 触发器。 | 要验证`EventSourceCustomer`触发器，请使用`EventSourceCustomer`触发器的相应客户表和 CloudWatch 日志，重复此长篇故事中的步骤。 | 应用程序开发人员 | 

## 相关资源
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-resources"></a>

**参考**
+ [Visual Studio 2019 Community Edition 下载](https://visualstudio.microsoft.com/downloads/)
+ [AWS Toolkit for Visual Studio 下载](https://aws.amazon.com/visualstudio/)
+ [AWS Toolkit for Visual Studio 用户指南](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html)
+ [Serverless on AWS](https://aws.amazon.com/serverless/)
+ [DynamoDB 用例与设计模式](https://aws.amazon.com/blogs/database/dynamodb-streams-use-cases-and-design-patterns/)
+ [Martin Fowler CQRS](https://martinfowler.com/bliki/CQRS.html)
+ [Martin Fowler 事件溯源](https://martinfowler.com/eaaDev/EventSourcing.html)

**视频**
+ [AWS Toolkit for Visual Studio 演示](https://www.youtube.com/watch?v=B190tcu1ERk)
+ [如何为新 IAM 用户创建访问密钥 ID？](https://www.youtube.com/watch?v=665RYobRJDY)

## 附加信息
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional"></a>

**CQRS 和事件溯源**

*CQRS*

CQRS 模式将单个概念操作模型（例如数据访问对象单个 CRUD（创建、读取、更新、删除）模型）分离为命令和查询操作模型。命令模型是指任何更改状态的操作，如创建、更新或删除。查询模型是指任何返回值操作。

![\[包含服务接口、CRUD 模型以及数据库的架构。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/3f64756d-681e-4f0e-8034-746263d857b2.png)


1. 客户 CRUD 模型包含以下接口：
   + `Create Customer()`
   + `UpdateCustomer()`
   + `DeleteCustomer()`
   + `AddPoints()`
   + `RedeemPoints()`
   + `GetVIPCustomers()`
   + `GetCustomerList()`
   + `GetCustomerPoints()`

随着您的需求变得更加复杂，您可放弃这种单一模型方法。CQRS 使用命令模型和查询模型分离写入和读取数据的职责。这样就可以独立维护和管理数据。通过明确职责分工，对每个模型的增强不会影响其他模型。这种分离可改善维护和性能，并随着应用程序的增长降低其复杂性。

![\[该应用程序分为命令模型与查询模型，共享一个数据库。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/12db023c-eb81-4c27-bbb9-b085b13176ae.png)


 

1. 客户命令模型接口：
   + `Create Customer()`
   + `UpdateCustomer()`
   + `DeleteCustomer()`
   + `AddPoints()`
   + `RedeemPoints()`

1. 客户查询模型接口：
   + `GetVIPCustomers()`
   + `GetCustomerList()`
   + `GetCustomerPoints()`
   + `GetMonthlyStatement()`

有关示例代码，请参阅*源代码目录*。

然后，CQRS 模式可解耦数据库。这种解耦使每项服务能完全独立，这是微服务架构的主要组成部分。

![\[命令模型和查询模型数据库分开。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/016dbfa8-3bd8-42ee-afa1-38a98986c7d5.png)


 在 Amazon Web Services Cloud 中使用 CQRS，您可进一步优化每项服务。例如，您可设置不同的计算设置，或者在无服务器或基于容器的微服务之间进行选择。您可以用 Amazon 替换您的本地缓存 ElastiCache。如果您有本地 publish/subscribe 消息，则可以将其替换为亚马逊简单通知服务 (Amazon SNS) Service。此外，您还可以利用 pay-as-you-go定价和各种 AWS 服务，这些服务只需按实际用量付费。

CQRS 可提供以下优势：
+ 独立扩展 — 每个模型都可调整其扩展策略，以满足服务要求和需求。与高性能应用程序类似的是，将读写分离可以使模型独立扩展，以满足每种需求。您还可以添加或减少计算资源，以满足模型的可扩展性需求，而不影响另一种模型。
+ 独立维护 — 查询模型和命令模型的分离改进了模型的可维护性。您可在不影响另一个模型的情况下对一个模型进行代码更改和增强。
+ 安全 - 可以更轻松地将权限和策略应用于不同的读取和写入模型。
+ 优化读取 - 您可定义针对查询进行优化的架构。例如，您可为聚合数据定义一个架构，为事实表定义一个单独的架构。
+ 集成 – CQRS 非常适合基于事件的编程模型。
+ 托管复杂性 — 查询和命令模型的分离适合复杂的领域。

使用 CQRS 时，请记住以下注意事项：
+ CQRS 模式仅适用于应用程序的特定部分，不适用于整个应用程序。如果在不适合该模式的领域实施，它会降低生产力、增加风险和引入复杂性。
+ 该模式最适合具有不平衡读写操作的常用模型。
+ 对于读取量大的应用程序（例如需要时间处理的大型报告），CQRS 使您可以选择正确的数据库，并创建一个架构以存储聚合数据。通过仅处理一次报告数据并将其转储到聚合表中，可以提高读取和查看报告的响应时间。
+ 对于写入量大的应用程序，您可以配置数据库进行写入操作，并允许命令微服务在写入需求增加时独立扩展。有关示例，请参阅 `AWS.APG.CQRSES.CommandRedeemRewardLambda` 和 `AWS.APG.CQRSES.CommandAddRewardLambda` 微服务。

*事件溯源*

下一步，在运行命令时使用事件溯源同步查询数据库。例如，请考虑以下事件：
+ 添加客户奖励积分，要求更新查询数据库中的客户总奖励积分或汇总奖励积分。
+ 在命令数据库中更新客户姓氏，这要求更新查询数据库中的代理客户信息。

在传统 CRUD 模型中，您可通过锁定数据直到完成事务来确保数据的一致性。在事件溯源中，通过发布一系列事件来同步数据，订阅用户将使用这些事件来更新其各自的数据。

事件溯源模式可确保并记录一系列数据操作，并通过一系列事件将其发布。这些事件表示：该事件的订阅用户为保持记录更新而必须处理的一系列数据更改。这些事件由订阅用户使用，用于同步订阅用户数据库的数据。在本例中，就是查询数据库。

下图显示了 AWS 上与 CQRS 共用的事件溯源。

![\[使用 AWS 无服务器服务的 CQRS 和事件溯源模式的微服务架构。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/cc9bc84a-60b4-4459-9a5c-2334c69dbb4e.png)


1. 命令 Lambda 函数对数据库执行写入操作，如创建、更新或删除。

1. 查询 Lambda 函数对数据库执行读取操作，如获取或选择。

1. 此 Lambda 函数处理来自命令数据库的 DynamoDB 数据流，并更新查询数据库以获取更改。您也可使用此功能向 Amazon SNS 发布消息，以便其订阅用户可以处理数据。

1. （可选）Lambda 事件订阅用户处理 Amazon SNS 发布的消息，并更新查询数据库。

1. （可选）Amazon SNS 会发送有关写入操作的电子邮件通知。

在 AWS 上，查询数据库可通过 DynamoDB Streams 进行同步。DynamoDB 可在 DynamoDB 表中捕获按时间排序的项目级修改序列，并在 24 个小时内持久存储信息。

激活 DynamoDB Streams 使数据库能发布一系列事件，从而使事件溯源模式成为可能。事件溯源模式添加事件订阅用户。事件订阅用户应用程序使用事件，并根据订阅用户的责任进行处理。在上图中，事件订阅用户将更改推送至查询 DynamoDB 数据库以保持数据同步。Amazon SNS、消息代理和事件订阅用户应用程序的使用，使架构保持独立。

事件溯源包括以下优势：
+ 事务数据的一致性
+ 可靠的审计跟踪记录和操作历史记录，可用于监控数据中采取的操作
+ 允许微服务等分布式应用程序在整个环境中同步数据
+ 当状态发生变化时，都能可靠地发布事件
+ 重建或重现过去状态
+ 松散耦合实体，用于交换事件以从单体应用程序迁移至微服务
+ 减少由并发更新引起的冲突；事件溯源避免了直接在数据存储中更新对象的要求
+ 通过将任务和事件脱钩，来实现灵活性和可扩展性
+ 外部系统更新
+ 单个事件中管理多项任务

使用事件溯源时，请记住以下注意事项：
+ 由于源订阅用户数据库之间的数据更新会有延迟，因此撤消更改的唯一方法是向事件存储中添加补偿事件。
+ 因为其编程风格不同，因此实现事件溯源需要学习曲线。

**测试数据**

成功部署后，使用以下数据测试 Lambda 函数。

**CommandCreate Customer**

```
{  "Id":1501,  "Firstname":"John",  "Lastname":"Done",  "CompanyName":"AnyCompany",  "Address": "USA",  "VIP":true }
```

**CommandUpdate Customer**

```
{  "Id":1501,  "Firstname":"John",  "Lastname":"Doe",  "CompanyName":"Example Corp.",  "Address": "Seattle, USA",  "VIP":true }
```

**CommandDelete Customer**

输入客户 ID 为请求数据。例如，如果客户 ID 为 151，则输入 151 为请求数据。

```
151
```

**QueryCustomerList**

此值为空。当它被调用时，将返回所有客户。

**CommandAddReward**

这将为身份为 1 的客户 (Richard) 增加 40 点积分。

```
{
  "Id":10101,
  "CustomerId":1,
  "Points":40
}
```

**CommandRedeemReward**

这将扣除 ID 为 1 的买家 (Richard) 的 15 点积分。

```
{
  "Id":10110,
  "CustomerId":1,
  "Points":15
}
```

**QueryReward**

输入客户 ID。例如，为 Richard 输入 1，为 Arnav 输入 2，为 Shirley 输入 3。

```
2 
```

**源代码目录**

使用下表指导，以了解 Visual Studio 解决方案的目录结构。 

*CQRS 本地代码示例解决方案目录*

![\[命令和查询服务已扩展的解决方案目录。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/4811c2c0-643b-410f-bb87-0b86ec5e194c.png)


**客户 CRUD 模型**

CQRS On-Premises Code Sample\$1CRUD Model\$1AWS.APG.CQRSES.DAL 项目

**客户 CRUD 模型的 CQRS 版本**
+ 客户命令：`CQRS On-Premises Code Sample\CQRS Model\Command Microservice\AWS.APG.CQRSES.Command` 项目
+ 客户查询：`CQRS On-Premises Code Sample\CQRS Model\Query Microservice\AWS.APG.CQRSES.Query` 项目

**命令和查询微服务**

Command 微服务位于解决方案文件夹 `CQRS On-Premises Code Sample\CQRS Model\Command Microservice`：
+ `AWS.APG.CQRSES.CommandMicroservice` ASP.NET Core API 项目充当使用者与服务交互的入口。
+ `AWS.APG.CQRSES.Command` .NET Core 项目是托管与命令相关的对象和接口的对象。

查询微服务位于解决方案文件夹 `CQRS On-Premises Code Sample\CQRS Model\Query Microservice`：
+ `AWS.APG.CQRSES.QueryMicroservice` ASP.NET Core API 项目充当使用者与服务交互的入口。
+ `AWS.APG.CQRSES.Query` .NET Core 项目是托管与查询相关的对象和接口的对象。

*CQRS AWS 无服务器代码解决方案目录*

![\[显示微服务和事件源已扩展的解决方案目录。\]](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/23f8655c-95ad-422c-b20a-e29dc145e995.png)


 

此代码是使用 AWS 无服务器服务本地代码的 AWS 版本。

在 C\$1 .NET Core 中，每个 Lambda 函数都由一个 .NET 核心项目表示。在此模式示例代码中，命令和查询模型中的每个接口都包含一个单独的项目。

**使用 Amazon Web Services 的 CQRS**

您可在 `CQRS AWS Serverless\CQRS` 文件夹中找到使用 AWS 无服务器服务的 CQRS 的根解决方案目录。该示例包括两个模型：即“客户” 和“奖励”。

客户和奖励的 Lambda 命令函数位于 `CQRS\Command Microservice\Customer` 和 `CQRS\Command Microservice\Reward` 文件夹。它们包含以下 Lambda 项目：
+ 客户命令：`CommandCreateLambda`、`CommandDeleteLambda` 和 `CommandUpdateLambda`
+ 奖励命令：`CommandAddRewardLambda` 和 `CommandRedeemRewardLambda`

“客户”和“奖励”的 Lambda 查询函数位于 `CQRS\Query Microservice\Customer` 和 `CQRS\QueryMicroservice\Reward` 文件夹下。它们包含 `QueryCustomerListLambda` 和 `QueryRewardLambda` Lambda 项目。

**CQRS 测试项目**

测试项目位于 `CQRS\Tests` 文件夹下。该项目包含用于自动测试 CQRS Lambda 函数的测试脚本。

**使用 Amazon Web Services 的事件溯源**

以下 Lambda 事件处理程序由客户和奖励 DynamoDB 流启动，旨在用于处理和同步查询表中的数据。
+ `EventSourceCustomer` Lambda 函数映射到客户表 (`cqrses-customer-cmd`) DynamoDB 流。
+ `EventSourceReward`Lambda 函数映射到奖励表 (`cqrses-reward-cmd`) DynamoDB 流。

## 附件
<a name="attachments-9f1bc700-def4-4201-bb2d-f1fa27404f15"></a>

要访问与此文档相关联的其他内容，请解压以下文件：[attachment.zip](samples/p-attach/9f1bc700-def4-4201-bb2d-f1fa27404f15/attachments/attachment.zip)