ENode框架Conference案例分析系列之 - 架构设计
Conference架构概述
先贴一下Conference案例的在线地址,UI因为完全拿了微软的实现,所以都是英文的,以后我有空再改为中文的。
- Conference后台会议管理:http://www.enode.me/conference
- Conference前台预定座位:http://www.enode.me/registration
- ENode论坛开源案例:http://www.enode.me/post
- ENode开源项目地址:https://github.com/tangxuehua/enode
前一篇文章介绍了Conference案例的上下文划分和领域模型的设计思路,本文想介绍一下Conference案例的架构设计。我做Conference案例的出发点是为了给大家展示如何使用ENode框架来开发DDD+CQRS+ES+EDA风格的应用程序。所以,Conference案例的架构自然就是使用这个架构了。下面我展开来说一下:
- DDD:是软件设计的一种方式,出发点是通过领域模型封装业务逻辑和业务规则,解决领域内的复杂业务问题;
- CQRS+ES:命令查询分离的架构,通过将命令查询分离,做到处理业务逻辑的部分和查询的部分可以分离,方便两部分可以各自发展,不受对方约束;CQRS的实现方式主要有两种:1)共享存储的CQRS,即背后的数据库存储是一份,数据是一份,只是在代码、架构层面做到命令和查询逻辑的分离。这种方式很好的利用了CQRS的思想,同时也不会有数据一致性的问题,因为是共享存储的,所以CQ两端不需要有消息通信,大部分应用程序用这种方式即可。2)存储分离的CQRS,这种方式主要用ES(Event Sourcing,事件溯源)技术来彻底实现CQ两端的完全分离,这种架构比较复杂。C端不存储对象的最新状态,而是存储对象产生的所有事件;让我们要还原一个对象时,通过ES的方式来还原。然后Q端通过订阅C端产生的事件来更新读库。这种架构是一种EDA的架构,CQ两端需要通过事件来进行联系,所以是一种面向最终一致性思路的架构。那这种方式有何好处呢?它和前面我说的第一种方式的CQRS架构,我觉得主要的好处是,我们可以设计一套框架,帮我们从架构层面解决并发问题、消息的幂等处理问题;同时结合in-memory, group commit等技术,还能大大提高系统的吞吐量以及抵御高峰的能力(因为消息可以堆积);从而可以让开发人员不用关心技术问题,专心实现业务逻辑和设计业务流程即可。而共享存储的CQRS架构,是需要我们每次Command修改完聚合根之后,需要主动保存(可能通过ORM实现)聚合根的状态的。总之两种实现方式各有优缺点,关于CQRS架构的更多介绍,我博客里已经写过很多文章了,有兴趣的朋友可以进一步看看。
- EDA:这是一种事件驱动的架构,他和SOA架构属于同一个层次;EDA是事件驱动的思想,即B订阅A产生的消息来进行主动响应的思路;而SOA是一种面向服务然后通过服务之间相互调用(RPC)的思想;这是两种不同的架构风格,我们在不同的场景会使用不同的方式。ENode实现的是EDA架构,面向的是最终一致性。ENode在很多方面都体现出了EDA的思想。比如:
- ENode规定,一个Command不能同时修改两个聚合根,必须通过事件驱动的方式,先修改一个聚合根,然后该聚合根产生事件,然后另一个聚合根订阅响应事件,再修改自己的状态,从而实现两个聚合根之间的交互。这个思路 背后的原则是:聚合内强一致性、聚合之间最终一致性。
- CQRS两端,也是最终一致性,通过事件来同步数据。C端产生的事件通过MQ被Q端订阅,然后Q端更新自己的读库,从而实现数据的最终一致性;
- 两个BC(Bounded Context,上下文)之间的数据传递,也是基于消息驱动的思想。比如支付上下文在完成支付后,会产生一个消息,然后订单上下文订阅响应该消息,实现上下文之间的交互。
ENode架构图
也许有人没看过ENode架构图,呵呵。我这里再贴一下,谁如果要进一步了解ENode的架构设计,可以看我博客中的其他关于ENode框架的介绍文章。
Conference项目结构介绍
|
前篇文章中我们了解到,Conference案例共有三个上下文,分别是:会议管理(ConferenceManagement)、订单处理(Registration)、订单支付(Payment)。关于这个案例,微软的实现和我的实现有所不同,但上下文的划分是一致的。微软的实现中,三个上下文用的技术架构是不同的。
上面我简要分析了一下微软的实现。我觉得微软的实现还是非常有参考价值的,因为它充分展示了DDD中不同的BC可以采用不同的技术架构实现,然后通过EDA的整体架构,来实现3个BC之间的数据交互。非常棒。 下面我说一下ENode实现的Conference案例。 前面说过,本案例主要是为了展示ENode框架的使用,所以我给这3个BC都是使用ENode框架实现,所以每个BC都是采用的DDD+CQRS+ES的技术架构。由于有ENode框架的支持,所以代码实现还不算复杂,可以让开发只需要专注于业务逻辑的实现即可,不需要关心消息传递,消息不丢失,消息幂等处理,并发问题,C端数据持久化等技术问题。这些技术问题如果没有框架支持,要由应用开发人员自己实现,是很有难度的。通过这个案例实践下来,基本可以证明ENode框架是可以被使用来开发出一个可实际使用的项目的,这点我目前很有信心。 采用ENode框架开发一个BC的实现的时候,我们一般需要定义以下的一些工程:
另外,上面介绍了单个BC内部可能出现的项目,这些项目是我通过做这个案例后总结出来的觉得可以给开发者做参考的相互划分方式。大家如果觉得这样的方式不好,可以自己决定如何划分。通过上面的划分,我们的顶层Web项目只需要依赖简单的Commands,ReadModel这两个项目,就可以实现命令的发送和读库数据的查询了。而BC之间的交互,另一个BC只需要依赖当前BC的Messages项目就行,做到了最小的依赖。 最后介绍一下剩余的几个顶层项目: Conference案例有两个Web项目,分别为用户提供Conference的后台管理和前台订单预定的Web界面。这个不需要多解释了应该。然后,还有3个ProcessorHost项目。这3个项目分别是3个BC负责处理后台业务逻辑的顶层宿主项目。它们只需要用控制台应用或者Windows服务的方式启动即可(案例里的实现同时支持这两种方式的启动,会自动识别当前的应用程序类型)。这3个后台服务,它们都是从EQueue订阅消息,然后处理消息的方式,实现自己的功能。所以它们的唯一数据来源就是EQueue。那EQueue消息队列的服务端是哪个呢?就是最下面的MessageBroker,这个项目承载了整个系统的消息中心,也就是EQueue的Broker。所有的消息都会发送给MessageBroker,然后相关的ProcessorHost订阅相关的Topic,实现消息的消费。 |
结尾
下一篇文章打算从代码的角度,以创建一个会议为例,从前台Controller到最后更新读库的整个代码链路简单介绍一下,方便读者能对实现某个功能要写哪些代码先有一个清晰总体的认识。
ENode框架Conference案例分析系列之 - 架构设计的更多相关文章
- ENode框架Conference案例分析系列之 - 文章索引
ENode框架Conference案例分析系列之 - 业务简介 ENode框架Conference案例分析系列之 - 上下文划分和领域建模 ENode框架Conference案例分析系列之 - 架构设 ...
- ENode框架Conference案例分析系列之 - 复杂情况的读库更新设计
问题背景 Conference案例,是一个关于在线创建会议(类似QCon这种全球开发者大会).在线管理会议位置信息.在线预订某个会议的位置的,这样一个系统.具体可以看微软的这个项目的主页:http:/ ...
- ENode框架Conference案例分析系列之 - 订单处理减库存的设计
前言 前面的文章,我介绍了Conference案例的业务.上下文划分.领域模型.架构,以及代码整体流程.接下来想针对案例中一些重要的场景,分别做进一步的分析.本文想先介绍一下Conference案例的 ...
- ENode框架Conference案例分析系列之 - Quick Start
前言 前一篇文章介绍了Conference案例的架构设计,本篇文章开始介绍Conference案例的代码实现.由于代码比较多,一开始就全部介绍所有细节,估计很多人接受不了,也理解不了.所以,我先进行一 ...
- ENode框架Conference案例分析系列之 - 事件溯源如何处理重构问题
前言 本文可能对大多数不太了解ENode的朋友来说,理解起来比较费劲,这篇文章主要讲思路,而不是一上来就讲结果.我写文章,总是希望能把自己的思考过程尽量能表达出来,能让大家知道每一个设计背后的思考的东 ...
- ENode框架Conference案例分析系列之 - 上下文划分和领域建模
前面一片文章,我介绍了Conference案例的核心业务,为了方便后面的分析,我这里再列一下: 业务描述 Conference是这样一个系统,它提供了一个在线创建会议以及预订会议座位的平台.这个系统的 ...
- ENode框架Conference案例分析系列之 - ENode框架初始化
前言 Conference案例是使用ENode框架来开发的.之前我没有介绍过ENode框架是如何启动的,以及启动时要注意的一些点,估计很多人对ENode框架的初始化这一块感觉很复杂,一头雾水.所以,本 ...
- ENode框架Conference案例分析系列之 - 业务简介
前言 ENode是一个应用开发框架.通过ENode,我们可以方便的开发基于DDD+CQRS+EventSourcing+EDA架构的应用程序.之前我已经写了很多关于ENode的架构以及设计原理的文章, ...
- ENode框架Conference案例转载
ENode框架Conference案例分析系列之 - Quick Start 前言 前一篇文章介绍了Conference案例的架构设计,本篇文章开始介绍Conference案例的代码实现.由于代码比较 ...
随机推荐
- AgileEAS.NET SOA 中间件平台.Net Socket通信框架-介绍
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- Python-基础数据类型
数据类型 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同的数据,需要定 ...
- MySQL开发规范
字段设计 (1)建议使用UNSIGNED存储非负数值. (2)建议使用INT UNSIGNED存储IPV4. (4)INT类型固定占用4字节存储,例如INT(4)仅代表显示字符宽度为4位,不代表存储长 ...
- android_studio上传svn的时候那些不提交
buid文件夹不需要提交
- AOP详解
什么是AOP AOP Aspect Oriented Programing 面向切面编程 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存) Spring ...
- C/C++ 知识点1:内存对齐
预备知识:基本类型占用字节 在32位操作系统和64位操作系统上,基本数据类型分别占多少字节呢? 32位操作系统: char : 1 int :4 short : 2 unsigned ...
- 解决谷歌浏览器中的input背景色默认是黄色
input:-webkit-autofill { -webkit-box-shadow: 0 0 0px 1000px white inset !important; }
- .NET开发人员必看:提高ASP.NET Web应用性能的24种方法和技巧
那性能问题到底该如何解决?以下是应用系统发布前,作为 .NET 开发人员需要检查的点. 1.debug=「false」 当创建 ASP.NET Web应用程序,默认设置为「true」.开发过程中,设置 ...
- CustomUI Direct3D9_Sample
刚开始建这个项目的时候编译器报了很多Link2019的错误. 后来添加了一些lib文件才解决,参考 缺少.lib文件导致的Link2019 解决方案汇总 ==================== ...
- jQuery数据缓存方案详解:$.data()的使用
我们经常使用隐藏控件或者是js全局变量来临时存储数据,全局变量容易导致命名污染,隐藏控件导致经常读写dom浪费性能.jQuery提供了自己的数据缓存方案,能够达到和隐藏控件.全局变量相同的效果,但是j ...