使用Axon Framework探索CQRS架构系列(零):介绍

8 篇文章 2 订阅
7 篇文章 0 订阅

原文地址:http://www.geekabyte.io/2015/10/exploring-cqrs-architecture-with-axon.html

这是使用Axon Framework探索CQRS架构的一系列中的第一篇文章。

目的是首先从概念/架构的角度理解CQRS是什么,然后探索Axon Framework框架,以帮助构建遵循CQRS模式的应用程序。

本系列的帖子包括:

使用Axon Framework探索CQRS架构系列(一):命令, 命令总线 和 命令处理组件
使用Axon Framework探索CQRS架构系列(二):DDD一些概念的概览
使用Axon Framework探索CQRS架构系列(三):构建实体、聚合、聚合根、存储库组件
使用Axon Framework探索CQRS架构系列(四):介绍领域事件及事件处理
使用Axon Framework探索CQRS架构系列(五): 事件溯源 Event Sourcing的应用
Exploring CQRS with Axon Framework: Overview of the Testing infrastructure.
Exploring CQRS with Axon Framework: Closing thoughts.

What is CQRS

CQRS是一种构建软件系统的方法,强调分离应用程序中改变应用程序状态的部分和查询应用程序状态的部分。 我们在以下部分进一步扩展:“CQRS的鸟瞰图”。

What is Axon Framework

Axon Framework标语说:“CQRS框架 for Java”。 我想这似乎总结了一下? Axon Framework将自身描述为一个框架,通过支持开发人员应用命令查询责任隔离(CQRS)架构模式,帮助构建可伸缩,可扩展和可维护的应用程序。 它通过提供最重要的构建块的实现来实现,例如聚合,存储库和事件总线(事件的调度机制)

您可以在此处阅读有关此内容和Axon Framework背景的更多信息。

在我们开始研究Axon Framework为构建CQRS应用程序提供的构建块之前,让我们首先概述一下CQRS的内容。 如果您已经熟悉CQRS,并且只想了解Axon Framework如何为您提供帮助,那么请随时跳转到命令,命令总线和命令处理组件

A bird’s eye view of CQRS

我喜欢将CQRS视为一个简单概念的繁琐首字母缩略词,即应用程序的“write”部分与应用程序的“read“部分明显分开。

如果你看一下这个首字母缩略词的定义,那基本上就是说:Command(写入部分),Query(读取部分)Responsibility Segregation(应该分开)。

例如,如果我有这样一个类foo

public class Foo {

// changes state
private void makeFoo() {
}

// reads state
private Foo getFoo() {
}

改变状态和读取状态的功能责任分为两种方法,但它们仍然非常紧密地联系在一起,因为它们存在于同一类中,因此无法将它们明确地分开。

将getFoo()移动到另一个类,并将makeFoo()页移动到另一个类,实现了一些分离:CQRS是关于在基础结构级别而不仅仅是在类级别上实现这种分离。

这就是它的全部……

实现此分离的确切方法是保持开放,并且未在CQRS定义中指定。

但我们会注意到,根据CQRS规定的这个定义的本质,松散耦合最终成为CQRS的概念所固有的。 因此,我们经常发现基于组件和事件/消息驱动的设计作为通常用于实现CQRS的方法。

在某些方面/讨论中,CQRS甚至不被视为“架构”而是“模式”。 一种模式或方法,在遵循时可以打开空间以应用不同的其他架构来帮助实现。

在我看来,这是第一次接触CQRS时的混乱。 例如,我敢打赌,一旦你开始涉足CQRS,你几乎会立即接触到诸如事件溯源,最终一致性,消息和actor等概念。这最终会反映出CQRS所代表的想法。

例如,当提到CQRS时,事件溯源总是几乎一起出现在你的面前,所以你会认为它在技术上是CQRS的一部分,尽管事实并非如此。 您可以拥有一个没有事件溯源的CQRS系统!

我简单概括,事情变得更加清晰:CQRS很简单,它只是说写和读应该分开。 但由于松散耦合为我们开辟了基础,基于组件的方法,由消息驱动已经成为实现CQRS的最流行的方式之一。

下一个问题是构成典型CQRS设置的组件是什么? 或者更确切地说,Axon框架为其提供基础架构的组件。

为了回答这个问题,我们将使用分层架构进行比较。

分层架构 vs 基于组件的架构

在分层体系结构中,应用程序的各个部分(组件)排列在层中,具有一个独特的特征,即一个层只能直接调用它下面的层。

也就是说,一层紧密地耦合到它旁边的层。
像这样:
web-layer
source: https://dotnetpeoples.wordpress.com/2011/05/16/three-tier-architecture-in-asp-net/

或者这样
crazy-layer

取决于你想要架构分的层数的疯狂程度。

订单上的基于组件的体系结构有利于通过使半自治组件松散耦合,并且能够使用消息传递机制与其他组件协作和通信来构建应用程序。

Component-based-Software-Engineering-example2

CQRS应用程序通常包括以下组件:UI,命令总线,命令处理程序,存储库,域对象,事件总线,事件处理程序,以及通过命令和事件组合在一起的所有组件。

这些组件如下所示:

cqrs

蓝色部件是您的应用程序组件。 绿色的是Axon Framework提供的组件(尽管值得注意的是Axon很容易让您提供自己的组件实现…例如,您可以轻松地将命令总线的实现交换为自定义实现)。

从图中可以看出,顶部的组件是改变应用程序状态的组件。 它也是实现业务逻辑的领域,而底部的组件读取或查询应用程序的状态:在这种明确的分离中,我们有了CQRS。

应用程序中的流程总结为:

使用UI组件的用户启动改变状态的意图(预订票证,编辑文档,更新医疗记录等)。 这种改变状态的意图被建模为命令命令被传递到命令总线,命令总线找到可以处理用户发起的命令的必要命令处理程序

状态更改在Command处理程序中处理,该处理程序使用Repository加载Domain对象并执行业务逻辑,将更改应用于其状态。

一旦状态发生变化,代表更改内容的事件将发布到事件总线。 事件总线确保通知到必要的事件处理程序。 然后,事件处理程序更新应用程序状态的表示,然后UI可以查询该状态。 在某些情况下,如果需要,您还可以启动命令以响应事件。

Where Event Sourcing comes in.

事件溯源的背后的想法是,我们存储改变应用程序的事件,而不是存储应用程序的当前状态。
事件溯源可以很容易地用于CQRS系统,但这并不意味着CQRS系统必须使用事件溯源。
您可以拥有完美的CQRS架构而无需事件溯源。Axon Framework提供了轻松使用事件溯源的工具。

What Next?

现在我们已经对CQRS进行了概述,看到了将要发挥作用的各种组件,接下来的问题是,如何使用Axon Framework?

这些系列中即将发布的帖子将正是如此。 我们将探索如何使用Axon Framework提供的工具构建CQRS应用程序的各种组件。

为了帮助说明本系列中将要涉及的主题,我在Github上创建了一个项目https://github.com/dadepo/exploringCQRSwithAxon。 这是一个简单的应用程序,可以为两个银行账户建模,并具有借记和贷记账户的能力。

本系列中的每篇文章都将以关于需要在其他方面检出的提交哈希的指令开始,以使项目处于该帖子的状态。

我们首先探索命令,命令总线和命令处理组件。

第1章我们的领域: 会议管理系统1 1.1Contoso公司简介1 1.2谁与我们同行2 1.3Contoso会议管理系统3 1.3.1系统概览3 1.3.2非功能性需求4 1.4开始我们的旅程5 1.5更多信息5 第2章领域分解——站点规划6 2.1本章术语定义6 2.2会议管理系统里面的有界上下文7 2.2.1订单和注册有界上下文7 2.2.2会议管理有界上下文7 2.2.3支付有界上下文8 2.2.4不包括在内的有界上下文8 2.2.5Contoso会议管理系统的上下文路线图9 2.3为什么选择这些有界上下文10 2.4更多信息11 第3章订单和注册有界上下文12 3.1订单和注册有界上下文简介12 3.2本章术语定义13 3.3领域定义(普适语言)14 3.4订单创建的需求分析16 3.5系统架构17探索CQRS和事件源目录3.6模式和概念17 3.6.1系统验证21 3.6.2交易边界22 3.6.3并发处理22 3.6.4Aggregates和Aggregate Roots22 3.7实现细节23 3.7.1高层架构23 3.7.2写者模型28 3.7.3使用Windows Azure服务总线37 3.8对测试的影响44 3.9本章小结47 3.10更多信息47 第4章扩展和改进订单和注册有界上下文48 4.1修改有界上下文48 4.1.1本章术语定义49 4.1.2用户需求49 4.1.3系统架构49 4.2模式和概念51 4.2.1记录定位器51 4.2.2读者端查询51 4.2.3向读者端提供部分履行的订单信息54 4.2.4CQRS命令验证55 4.2.5倒计时定时器和读者模型56 4.3实现细节56 4.3.1订单访问码(记录定位器)57 4.3.2倒计时定时器58 4.3.3使用ASP.NET MVC验证60 4.3.4将改动推送到读者端62 4.3.5重构SeatsAvailability aggregate66 4.4对测试的影响68 4.4.1接受测试和领域专家68 4.4.2使用SpecFlow功能来定义接受测试68 4.4.3通过测试来帮助开发人员理解消息流75 4.5代码理解的旅程: 痛苦、释放和学习的故事77 4.5.1测试很重要77 4.5.2领域测试78 4.5.3硬币的另外一面80 4.6本章小结83 4.7更多信息84 第5章准备V1发布85 5.1Contoso会议管理系统的V1发布版85 5.1.1本章术语定义85 5.1.2用户需求86 5.1.3系统架构87 5.2模式和概念91 5.2.1事件源91 5.2.2基于任务的用户界面92 5.2.3有界上下文之间的集成95 5.2.4分布式交易和事件源98 5.2.5自治与集权99 5.2.6读者端的实现方法100 5.2.7最终一致性100 5.3实现细节101 5.3.1会议管理有界上下文101 5.3.2支付有界上下文102 5.3.3事件源105 5.3.4基于Windows Azure表格的事件库111 5.3.5订单总价计算114 5.4对测试的影响114 5.4.1时序问题114 5.4.2引入领域专家115 5.5本章小结115 5.6更多信息115 第6章系统版本控制116 6.1本章术语定义116 6.1.1用户需求116 6.1.2系统架构117 6.2模式和概念118 6.2.1修改事件定义118 6.2.2确保消息的自洽性119 6.2.3集成事件的保存121 6.2.4消息排序122 6.3实现细节123 6.3.1对成本订单的支持123 6.3.2显示剩余座位数127 6.3.3删除重复命令130 6.3.4确保消息排序131 6.3.5保存会议管理有界上下文的事件135 6.3.6从V1版本迁移到V2版本139 6.4对测试的影响140 6.4.1重访SpecFlow140 6.4.2在迁移过程中发现错误143 6.5本章小结143 6.6更多信息144 第7章加入弹性和优化性能145 7.1本章术语定义145 7.2系统架构145 7.3加入弹性147 7.3.1增加事件重复处理时的弹性148 7.3.2确保命令的发送148 7.4优化性能148 7.4.1优化前的用户界面流程149 7.4.2用户界面优化150 7.4.3基础设施优化151 7.5无停机迁移158 7.6实现细节159 7.6.1改进RegistrationProcessManager类160 7.6.2用户界面流程优化165 7.6.3消息的异步接收、处理和发送170 7.6.4在流程内部对命令进行同步处理171 7.6.5使用备忘录模式来实现快照173 7.6.6对事件进行并行发布175 7.6.7在订购服务里面对消息进行过滤176 7.6.8为SeatsAvailability aggregate创建专门的SessionSubscriptionReceiver 实例177 7.6.9缓存读者模型数据179 7.6.10使用多个议题来划分服务总线180 7.6.11其他的优化和强化措施181 7.7对测试的影响184 7.7.1集成测试185 7.7.2用户界面测试185 7.8本章小结185 7.9更多信息185 第8章尾声: 经验教训186 8.1我们学到了什么186 8.1.1性能很重要186 8.1.2实现消息驱动并不简单187 8.1.3云平台的挑战187 8.1.4不同的CQRS188 8.1.5事件源和交易日志记录190 8.1.6引入领域专家190 8.1.7什么时候该使用CQRS190 8.2如果重新来过,我们会做的有什么不同191 8.2.1以牢靠的消息和保存基础设施为起点191 8.2.2更好地利用基础设施的能力191 8.2.3采纳更加系统化的方法来实现流程管理器192 8.2.4对应用程序实施不同的划分192 8.2.5以不同方式组织项目团队192 8.2.6对领域和有界上下文的CQRS适用性进行评估192 8.2.7为性能进行规划192 8.2.8重新考虑用户界面193 8.2.9探索事件源的其他用处193 8.2.10探索有界上下文的集成问题193 8.3更多信息194
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值