领域事件、事件溯源、事件风暴建模

事件代表过去发生的事件,事件既是技术架构概念,也是业务概念。以事件为驱动的编程模型称为事件驱动架构EDA,事件驱动与事件溯源EventSourcing是两种概念,EDA是技术架构概念,而事件溯源则是业务概念,兼具技术概念,“通过事件驱动”和”根据事件追溯跟踪源头“从词面意义上也是不同的。

一个事件代表某个已经发生的事情,在计算机系统中,事件是由一个对象表达,其包含有关事件的数据,比如发生的时间,地点等等。这个事件对象可以存在在一个消息或数据库记录或其他组件的形式中,这样一个对象称为"一个事件"。事件本身是不可变的值对象。

事件在技术架构上应用能提供无堵塞的高并发性能,如Nginx和Node.js,而Vert.x. 比 Node.js快好几倍?其他还有Event Stream Processing如Esper等,结合DDD实现的CQRS等。

事件概念业务系统中应用,诞生领域事件和EventSourcing等DDD实现方式:通过引入事件,类似服务概念一样,跨越业务和技术鸿沟,同时又能表达面向函数编程思维。在业务上将事件和领域驱动设计DDD结合在一起,可以形成统一语言DSL,事件是触发状态变化的根源。参考:荷兰还有媲美光刻机的软技术:组件建模和分析框架Comma为复杂软件提供了高可靠性 – Bits&Chips

领域事件是领域中发生的事件。如CustomerRelocated, CargoShipped, or InventoryLossageRecorded.

领域事件将领域模型的改变显式化,突出暴露出来。如下图:

事件日志

几乎所有数据库都支持高可用性集群,大多数数据库对系统一致性模型提供一个易于理解的方式,保证强一致性模型的安全方式是维持数据库事务操作的有序日志,理论上理由非常简单,一个事件日志是一系列数据更新操作的动作有序记录集合,当其他节点从主节点获得这个事件日志时,能够按照这种有序动作集合重新播放这些操作,从而更新自己所在节点的数据库状态,当这个事件日志完成后,次节点的状态最终会和主节点状态一致,

这种事件日志非常类似于财务中记账模型,或者类似银行储蓄卡打印出来的流水账,哪天存入一笔钞票(更新操作),哪天又提取了一笔钞票(更新操作),最后当前余额是多少(代表数据库当前状态)。

事件溯源Event Sourcing

Event sourcing事件溯源是借鉴数据库事件日志的一种数据持久方式,在事件日志中记录导致状态变化的一系列领域事件。通过持久化记录改变状态的事件,通过重新播放获得状态改变的历史。

事件回放可以返回系统到任何状态。

在ES中,事务单元变得更细粒度,使用一系列有序的事件来代表存储在数据库中的领域模型状态,一旦一个事件被加入事件日志,它就不能被移走或重新排序,事件被认为是不可变的,事件序列只能被追加方式存储。

由于事件流本身具有逻辑上严格次序性,因此使用统一的事件流(事件日志)能够很自然实现事务机制,无需额外ACID机制或2PC之类同步强硬方式。

函数式编程

在微服务等无状态应用架构中,我们不是需要状态时就发出命令从数据库中查询获得,这样,可变的状态会遍布整个应用代码中,带来很多副作用,而我们将这些状态操作统一为事件流声明式订阅,订阅了某个事件流,通过重播事件流中各个事件一直到最新最后的事件,也就获得了最终的状态。函数式编程Stream风格为这种播放提供了方便,具体Reactive框架有RxJS、React.js、RxJava、Reactor等等。

这种实现其实已经在Reactive前端中有着同样实现思路,见:为什么要使用GraphQL和Falcor?,应用程序(微服务)将可变的状态被限定在一个单个的序列化对象中,从而整个应用就变成了无态,可变状态不会扩散到整个应用代码的各个本地变量中。

我们甚至可以使用领域事件直接对业务需求进行事件建模,通过事件功能的发现挖掘需求中深层次的概念。动态流的事件模型加上结合DDD的聚合实体 状态 和上下文场景Bounded context,我们实际上统一了需求分析和软件设计两个阶段的语言,使用这套统一语言分析需求以后,能够直接落地为代码,如下图是总结了在Jdon多位牛人的思想后的Jdon分析法:

该图表达了用户操作者和被操作者事物之间的本质关系,以用户和购物车为案例,从购物车这个事物角度看:领域聚合实体表达的是购物车这个事物的分析设计方法,以一种静态结构性来表达事物;从用户购买者这个角度看:用户将选购的商品放入购物车,删除购物车已有商品,这些都是用户的操作行为,每一个操作行为相当于发出一个个命令command,在一定场景中转化为事件,事件会改变购物车状态,这是一种以动态行为(面向函数)来表达与人有关的需求。

事件建模原理,找出意图 执行和结果范式:

对应意图 执行和结果范式的事件风暴图:

通过引入事件概念,可以实现多线程并发到分布式去中心化计算的平滑过渡,区块链本质上就是一种事件链。 通常区块链是指一种分布式账簿,账本其实是记账明细,记录着每笔进出明细,这些发生的每笔明细其实代表系统发生的事件,因此,记账明细其实就是事件日志,区块链其实就是一种分布式事件链,只不过另外增加了一层安全层。

事件溯源的适用场景是和区块链的应用场景类似的,因为两者本质上是一致的,可以说区块链就是一种事件溯源,传统的集中式的事件溯源是将事件日志集中保存到事件库或Apache Kafka之类流处理框架,而区块链则是将事件日志分别保存在各个聚合所在的点,如何向这个大而全的事件日志写入新事件?传统分布式系统通过Paxos或Raft选举主节点单独向事件日志写入事件,而区块链通过工作证明算法选举,CRDT通过事件数据本身携带的向量时钟合并,可谓各有巧妙。

事件是BPMN流程建模元素,表示在流程过程中“发生”的事情,事件会影响流程的走向,事件主要分开始事件、中间事件和结束事件,所谓中间事件就是位于开始和结束之间的事件类型。什么是BPMN事件?

DDD、领域事件和BPMN流程和Saga可以有机结合在一起,详见Jdon框架:

相关文章

相关话题

java事件溯源_领域事件与事件溯源 - 解道Jdon相关推荐

  1. java lambda if_使用Java8的Lambda实现Monda -解道Jdon

    使用Java8的Lambda实现Monad Monad是函数语言(Cojure或Scala)中的设计模式概念, 那么现在为什么在Java中变得如此重要?因为Java从版本8以后引入了新的Lambda特 ...

  2. java ee7教程_JavaEE 7.0 Web技术教程 -解道Jdon

    JavaEE7.0 Web技术教程 Java平台企业版(Java EE )提供了一个基于标准开发Web和企业应用程序的平台.这些应用程序通常被设计 作为多层应用程序,用一个前端层组成的网络架构,一个 ...

  3. qgraphicsitem鼠标移动事件阻塞_常用的DOM事件

    用户界面事件:当用户与页面的上的元素交互时发生,但不一定与用户操作有关的事件. load事件:当页面加载完毕时在window上触发,当图像加载完毕时在ing元素上触发,等等,页面完全加载完毕(包括所有 ...

  4. java面试题_阿里大厂流出的数百道 Java 经典面试题

    BAT 常问的 Java基础39道常见面试题 1.八种基本数据类型的大小,以及他们的封装类 2.引用数据类型 3.Switch能否用string做参数 4.equals与==的区别 5.自动装箱,常量 ...

  5. java删除确认_删除添加确认事件

    停留的风 阅读(554) 评论(0)  编辑  收藏 所属分类: .NET技巧特辑 如何在DataGrid中点击删除时弹出确认,按"确定"时实施删除? 在datagrid的Item ...

  6. python事件循环_简单了解一下事件循环(Event Loop)

    关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...

  7. vue移动端点击事件延迟_去除点击事件300ms延迟 (使用了vue之后)

    因为习惯用vue了,再回到以前 采用获取dom节点来操作的写法 就觉得很麻烦. 我在 click 事件里面加了 tapmode 属性,在安卓里面没有300ms的延迟,但是在ios里面就会有这个问题. ...

  8. java enum 父类_枚举基类Enum详解

    本文主要是对枚举类型的基类Enum类做一个介绍: 首先,Enum类位于java.lang包下,根据类的介绍可以发现,Enum类是Java中所有枚举类的父类,将枚举作为一个set或者Map的keys来使 ...

  9. java udp 协议_网络协议 - UDP 协议详解

    ¶ 网络协议 - UDP 协议详解 基于TCP和UDP的协议非常广泛,所以也有必要对UDP协议进行详解.@pdai ¶ UDP概述 UDP(User Datagram Protocol)即用户数据报协 ...

最新文章

  1. 经常使用的npm命令
  2. mysql 数据库引擎介绍_MYSQL 数据库引擎介绍
  3. cocos2dx java 乱码_[cocos2d-x] --- 完美解决中文乱码
  4. python 中文乱码_python 解决cv2绘制中文乱码问题
  5. 数据库仓库管理系统课程设计
  6. 红米 android8 刷机,【红米6 安卓8.1线刷包】MIUI V9.6.7.0.OCGCNFD稳定版 线刷精简包...
  7. 电话销售的6个关键成功因素
  8. Twitter + Elasticsearch 数据分析总结
  9. Python3-网页爬取-批量爬取贴吧页面数据
  10. bequeath_conn
  11. 计算机系统安全启动,怎么关闭安全启动_关闭bios安全启动的方法图文步骤
  12. 高德地图自定义贴图图层
  13. FxCAD实验一 简单图形的绘制
  14. Python selenium —— 一定要会用selenium的等待,三种等待方式解读
  15. 古琴【A1】基本指法
  16. web canvas图片标点 得像素坐标数组
  17. 远程控制桌面,外网电脑PC手机ios安卓mac远程桌面连接内网linux和windows主机,史上最全最详细图文教程
  18. springboot+vue+elementui社区公益志愿者服务网站java
  19. 橘子学ES03之Docker安装ELK+cerebro
  20. 解决GAMIT10.71解算北斗二号三号观测值问题

热门文章

  1. CVE-2018-1273漏洞复现
  2. 如何修复损坏或损坏的照片呢?
  3. Java 基础 Collection集合
  4. “夜拍王”荣耀10GT上线,不用三脚架也能出夜景大片!
  5. [Django ]Django 的数据库操作
  6. 以前看的关于物联网的总结
  7. aix小机Java64位安装包,aix 5.3不能安装java1.4 64位
  8. 生活琐事(一)丢魂了
  9. win10计算机怎么新增用户,win10 如何添加管理员账户_win10 添加管理员账户方法-win7之家...
  10. 【MySQL数据库】 - 复杂查询(二)