Event Sourcing
Event Sourcing - ENode(二)
接上篇文章继续
http://www.cnblogs.com/dopeter/p/4899721.html
分布式系统
前篇谈到了我们为何要使用分布式系统,因为ENode本身就是一个分布式的框架。看了很多DDD、CQRS的框架,一般情况是一个上下文一个系统,可以多分系统实例进行分布式部署,但需要自己搭配分布式的基础设施。而ENode已经提供了较为完整的分布式DDD解决方案。
1. 分布式通讯基础设施
一般使用RPC、MOM、REST,不过最近REST已经逐渐弱化特别是在一个大系统的内部,或者是对性能要求较高的场景,作者自己实现并开源了MOM组件EQueue作为基础设施搭配ENode,有一些Kfaka的设计理念,但加入了自己的设想,可以到作者的博客上了解了解。
http://www.cnblogs.com/netfocus/category/496012.html
2. 分布式的粒度
这是ENode最大的亮点,从目前业内的发展的大方向来说,也是ENode能被投入生产环境试运行的原因之一。ENode是以Command、Event、Application Message、Exception为基础粒度采用的分布式设计。目前其他的CQRS框架大多都还是系统实例级的分布式,如果要实现这种粒度的分布式,需要自己动手设计,从长远来看,如果真的投入到生产环境,框架升级之后引发的不兼容等问题是很有可能的,当然ENode如果能成为我们目前OLTP系统的流行框架的话,还是得小心以后被作者绑架。
关系数据库
作者在框架中其实一直在使用关系数据库,因为有了前面粒度的铺垫,再加上ES本身的写屏障特性,实现了类似关系数据库的一致性,而只使用了关系数据库的持久化以及检查机制。当然作者在实现中仍然使用了事务,以及将关系数据库当分布式的锁来使用,有点类似ZooKeeper,这些都是基于的是粒度的缩小,所以性能上是有很大的提高。不过这些是作者的默认实现,我们可以自己实现另外一套。
其实应该从Sample开始讲的,不过如果有兴趣的朋友可以直接去下载作者的源码,作者的Sample写的很好,所以直接开剖。
全观

这是ENode的代码。
我们可以认为分为2层,开发者应用层(业务开发人员专用),基础设施层(架构开发人员专用) 。
Commanding,Domain,Eventing,Snapshoting属于应用层。是ES的专用术语。
Infrastructure和Configurations则是基础设施层。
Commanding

我们可以认为这是Commanding的装配图,顾名思义。
ICommand,一个命令

继承了IMessage,这就是前面提到的分布式消息。
其他的接口都是顾名思义。
ICommandHandler 命令处理者
ICommandHandlerProvider 隔离命令处理者的装配
ICommandHandlerProxy 命令处理者代理
Async则是代表异步的
就不一一介绍了。重点是看作者实现的默认的组件。

面向接口是代表作者抽象的高度与角度,真正代表其落地思想的则是其默认实现的类。
内容有点多,而且会很跳跃,这篇是讲不完的,我们还是慢慢来。主要是打字打的有点累了,手跟不上脑。先看看作者实现的DefaultProcessingCommandHandler类,
这是较为核心的,也可以认为是核心处理Command逻辑的类。
它实现了IProcessingMessageHandler接口,这个接口只有一个方法
void HandleAsync(X processingMessage);
于是我们就顺藤摸瓜看看作者的实现。


屏幕太小,截了2张图,第一张没什么特别的,第二张,这里使用了2个不同的Handler,一个是同步的,一个是异步的。它们的逻辑会有一些不同。
当然肯定是会执行Command的处理方法的。区别是什么呢?
在HandleCommand方法中,执行完后,有一些判断Command是否只是修改单个聚合根的逻辑,这里体现的是作者设计思想中的单个聚合根隔离性,也就是前篇所讲的关系数据库中事务隔离性粒度放至聚合根的粒度。在经过验证后,会直接提交Event,准备持久化Event,执行后续的,Event后续再讲。
在ProcessCommand方法中,用到了CommandStore,在作者默认实现的CommandStore中有2种实现方式,InMemory以及SQLSERVER,InMemory中是将Command存储在字典中,SQLSERVER则是以Command的ID作为主键,这里的逻辑是首先去CommandStore中检索是否存在相同ID的Command,如果有,则被证明是执行过了。如果没有,则继续执行Command,Command执行成功后,将Command保存至CommandStore中,保存成功后提交Event,准备持久化Event。这里实际上是在消除Command的幂等,第一个乐观锁机关出现了。
为什么第一个方法不使用乐观锁,而直接发布事件呢。
HandleCommand方法中的Command所对应的聚合根实际上还没有被更新,只是预提交一个Dirty的聚合根数据至EventHandler处,在EventHandler处会再次有乐观锁机关。
为什么ProcessCommand方法中要使用乐观锁呢,其实我没有完全的答案,猜测有以下几点
1. 见上图的If ,else if处,对一个Command来说,是可以有多个Handler的,无论是在系统实例内部或是其他并行的系统实例,再或者是其他上下文的系统实例,都有可能会有同步以及异步处理的Handler。
2. ProcessCommand方法是对应的异步CommandHandler,既然是异步的,作者使用了.NET的Task,虽然一个Command是单线程在跑,不过要是在异步中,例如我们和另外的系统通讯也使用了异步,那么这个线程就会返回,执行下一个Command,如果下一个Command相同,这个理论上是不大可能的。
3. MOM中消息的重复发送,这是有可能出现的。
Event Sourcing的更多相关文章
- Event Sourcing Pattern 事件源模式
Use an append-only store to record the full series of events that describe actions taken on data in ...
- CQRS, Task Based UIs, Event Sourcing agh!
原文地址:CQRS, Task Based UIs, Event Sourcing agh! Many people have been getting confused over what CQRS ...
- Typed Message模式与Event Sourcing
引言 在<设计模式沉思录>(Pattern Hatching: Design Patterns Applied,[美]JohnVlissides著)一书的第4章中,围绕事件Message传 ...
- DDD创始人Eric Vans:要实现DDD原始意图,必须CQRS+Event Sourcing架构
http://www.infoq.com/interviews/Technology-Influences-DDD# 要实现DDD(domain drive design 领域驱动设计)原始意图,必 ...
- Event Sourcing pattern
Event Sourcing pattern Instead of storing just the current state of the data in a domain, use an app ...
- DDD CQRS和Event Sourcing的案例:足球比赛
在12月11日新的有关DDD CQRS和Event Sourcing演讲:改变心态- 以更加面向对象视角看待业务领域建模中,作者以足球比赛football Match为案例说明传统编程方法和CQRS的 ...
- 事件溯源模式(Event Sourcing Pattern)
此文翻译自msdn,侵删. 原文地址:https://msdn.microsoft.com/en-us/library/dn589792.aspx 本文介绍了一种有利于物化(materialize)领 ...
- [外文理解] DDD创始人Eric Vans:要实现DDD原始意图,必须CQRS+Event Sourcing架构。
原文:http://www.infoq.com/interviews/Technology-Influences-DDD# 要实现DDD(domain drive design 领域驱动设计)原始意 ...
- 1.2 Use Cases中 Event Sourcing官网剖析(博主推荐)
不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ Event Sourcing 事件采集 Event sourcing is a st ...
随机推荐
- 逆向project第004篇:令计算器程序显示汉字(下)
一.前言 钩子技术是一项很有有用价值的技术.在Windows下HOOK技术的方法比較多,使用比較灵活,常见的应用层的HOOK方法有Inline HOOK(详见<反病毒攻防研究第012篇:利用In ...
- Codeforces 191 C Fools and Roads (树链拆分)
主题链接~~> 做题情绪:做了HDU 5044后就感觉非常easy了. 解题思路: 先树链剖分一下,把树剖分成链,由于最后全是询问,so~能够线性操作.经过树链剖分后,就会形成很多链,可是每条边 ...
- u-boot 的bootcmd 和bootargs详解,烧写分析
下面链接这篇文章也非常重要,介绍DM3X的一系列烧写步骤和设置方法 http://www.61ic.com/Article/DaVinci/TMS320DM3x/201204/41827.html U ...
- php获取前一天,前一个月,前一年的时间
获取前一天的时间: $mytime= date("Y-m-d H:i:s", strtotime("-1 day")); 获取三天前的时间: $mytime= ...
- Android中目的地Intent的使用
一.什么是Intent? Intent的中文意思是目的.在Android中也是“目的”的意思.就是我们要去哪里,从这个activity要前往另一个Activity就需要用到Intent. 示例代码一: ...
- 第三章 AOP 基于Schema的AOP
基于Schema定义的切面和前现两种方式定义的切面,内容上都差不多,只是表现形式不一样而已. 3.7.1一般增强的使用 a.目标类 public class Target { public void ...
- paip.关于动画效果的原则 html js 框架总结
paip.关于动画效果的原则 html js 框架总结 1. 动画框架的来源:flex,jqueryui 3 2. 特效的分类 3 2.1. Property effects 动态改变一个或多个目标对 ...
- Hadoop认知--在不同的阶段
入门阶段 出于兴趣,及工作中的简单有用,大约经过1个月的时间,完毕了对Hadoop的基本认知. 在这个月中我干了例如以下几件事 1.大体看了<Hadoop权威指南>.把里面的代码手工码了一 ...
- java Socket的怪异之处
怪异之一: connect(SocketAddress endpoint):这个方法,尝试连接server端,如果连接不上,就抛出IOException异常.如果连接成功了,就继续执行下一步的代码. ...
- FPGA机器学习之学习的方向
经过了2个月对机器学习的了解后.我发现了,机器学习的方向多种多样.网页排序.语音识别,图像识别,推荐系统等.算法也多种多样.看见其它的书后,我发现除了讲到的k均值聚类.贝叶斯,神经网络,在线学习等等, ...