CQRS和Event Sourcing系列(九):AxonFramework与SpringCloud的整合

上一篇里,我们在利用Axon3的DistributeCommand的JGroup支持,和DistributedEvent对AMQP的支持,实现了分布式环境下的CQRS和EventSourcing。
在这一篇中,我们将把Axon3与当下比较火热的微服务框架——SpringCloud进行整合,并将其微服务化。

写在前面的话

AxonFramework对SpringCloud的支持,是从3.0.2才开始的,但是在3.0.2和3.0.3两个版本,均存在blocking bug,所以要想与SpringCloud完成整合,版本必须大于等于3.0.4
PS:连续跳坑,debug读代码,帮Axon找BUG,血泪换来的结论……好在社区足够活跃,作者也比较给力,连续更新。

评论

CQRS和Event Sourcing系列(八):DistributeCommand和DistributeEvent

上一篇我们才算真正实现了一个基于Axon3的例子,本篇我们来尝试实现在分布式环境下利用Axon3做CQRS,即把CommandSide和QuerySide变成两个独立应用,分别可以启多份实例。

首先,我们回顾一下CQRS&EventSourcing模式下,整个架构的关键点,或者说最大的特点:

  • CommandSide和QuerySide的持久层分离;
  • 保存对Aggregate状态造成变化的Event,而不是状态本身;
  • Aggregate的状态全局原子化操作;
  • 适用于读大于写的场景;
    我们前面的例子,是在一个应用里面实现了CQRS模式,而在分布式场景下,有如下要求:
  • CommandSide和QuerySide可以不在同一个节点(甚至不在同一个应用)下;
  • CommandSide不同的CommandHandler、EventHandler可以不在同一个节点;
  • 不同CommandSide对同一个Aggregate的操作应具有原子性;
    我们来一步步满足这三个要求。

评论

CQRS和Event Sourcing系列(七):Saga的使用

在上一篇里面,我们正式的使用了CQRS模式完成了AXON的第一个真正的例子,但是细心的朋友会发现一个问题,创建订单时并没有检查商品库存。
库存是否足够直接回导致订单状态的成功与否,在并发时可能还会出现超卖。当库存不足时还需要回滚订单,所以这里出现了复杂的跨Aggregate事务问题。
Saga就是为解决这里复杂流程而生的。

Saga

Saga 这个名词最早是由Hector Garcia-Molina和Kenneth Salem写的Sagas这篇论文里提出来的,但其实Saga并不是什么新事物,在我们传统的系统设计中,它有个更熟悉的名字——“ProcessManager”,只是换了个马甲,还是干同样的事——组合一组逻辑处理复杂流程。
但它与我们平常理解的“ProgressManager”又有不同,它的提出,最早是是为了解决分布式系统中长时间运行事务(long-running business process)的问题,把单一的transaction按照步骤分成一组若干子transaction,通过补偿机制实现最终一致性。
举个例子,在一个交易环节中有下单支付两个步骤,如果是传统方式,两个步骤在一个事务里,统一成功或回滚,然而如果支付时间很长,那么就会导致第一步,即下单这里所占用的资源被长时间锁定,可能会对系统可用性造成影响。如果用Saga来实现,那么下单是一个独立事务,下单的事务先提交,提交成功后开始支付的事务,如果支付成功,则支付的事务也提交,整个流程就算完成,但是如果支付事务执行失败,那么支付需要回滚,因为这时下单事务已经提交,则需要对下单操作进行补偿操作(可能是回滚,也可能是变成新状态)。
可以看到Saga是牺牲了数据的强一致性,实现最终一致性。

评论

CQRS和Event Sourcing系列(六): 第一个正式Axon例子

前面对Axon的基本概念和基本操作做了简介,从本章开始,我们将一步步使用AxonFramework完成一个真正CQRS&EventSourcing的例子。

设计

回顾一下使用AxonFramework应用的架构

评论

CQRS和Event Sourcing系列(五): Axon使用EventSourcing和AutoConfigure

继上一篇集成SpringBoot后,本篇将继续完成小目标:

  1. 使用EventSourcing
  2. 使用AutoConfigure配置Axon

前一篇中看到配置Axon即便在Spring中也是比较麻烦的,好在Axon提供了spring-boot-autoconfigure,提供了Spring下的一些默认配置,极大地方便了我们的工作。
启用也是非常方便的,在上一篇的基础上,我们只需要干三件事即可达成目标:

  1. 引入spring-boot-autoconfigure
  2. 删除JpaConfig类
  3. 去除BankAccount中的Entity声明

评论

CQRS和Event Sourcing系列(四): Axon使用Jpa存储Aggregate状态

上一篇里,介绍了Axon的基本概念,并且做了一个最简单的hello例子。本篇将更进一步,完成两个小目标:

  1. 集成SpringBoot;
  2. 使用Standard Repository来存储Aggregate的最新状态。

1. 更新Maven依赖

干几件事:

评论

CQRS和Event Sourcing系列(三): Hello,Axon3

AxonFramework是一个轻量级的CQRS框架,支持EventSourcing,本系列将开始通过例子,StepByStep学习AxonFramework。

简介

AxonFramework是一个基于事件驱动的轻量级CQRS框架,既支持直接持久化Aggreaget状态,也支持采用EventSourcing,使用AxonFramework的应用架构如下

评论

CQRS和Event Sourcing系列(二):基本概念

在研究微服务的过程中,跨服务的操作处理,尤其是带有事务性需要统一commit或rollback的,是比较麻烦的。本系列记录了我在研究这一过程中的心得体会。
本篇主要就以下几个问题进行介绍:

  • 微服务中的一个大难题
  • DDD中的几个基本概念
  • 什么是EventSourcing?
  • 什么是CQRS?
  • EventSourcing和CQRS的关系?
  • CQRS/ES怎么解决微服务的难题?

微服务中的一个大难题

微服务架构已经热了有两年了,而且目测会越来越热,除非有更高级的架构出现。相关解释和说明,网上一搜一大堆,我这里就不重复了。一句话概括:
微服务将原来的N个模块,或者说服务,按照适当的边界,从单节点划分成一整个分布式系统中的若干节点上。

评论

CQRS和Event Sourcing系列(一):论精益与领域设计

开始之前

你是否遇到过这种事?一个“好”工程师,非常喜欢学习和钻研新的技术知识,JEE时代学习Spring,SSH时代学习分布式,大数据时代又开始学习Hadoop,Storm,云时代开始搞docker,k8……然后成长为一名“架构师”了,在他的公司,有一个重要项目,于是乎他决意把这个项目设计成一个全分布式的系统,毕竟“时髦”嘛。每一个小的开发团队负责分布式中的一个服务。由于架构师对这些程序员缺乏必要的指导和控制,每个程序员只熟悉自己负责的一小块工作,彼此间缺乏沟通和协作,这个项目的概念完整性很快就被破坏了,他们开始自行其事,分布式服务间大量的远程调用导致了性能和可伸缩性等多方面的问题,开发、测试、运维的工作难度与日递增。慢慢的,项目的开发人员,离职的越来越多,包含最初的架构师,代码的维护越来越难,最终只能重构,将十几个分布式服务合并为三个相对独立的集中应用。最初良好的架构,到最后沦为废墟。中间一位离职的程序员,换了一家公司,涨了一点工资,开始了另一段新系统建设的“狂欢”,周而复始,随着年龄的增大,他不再能够从软件开发中享受到乐趣,开发的生涯,对他来说痛苦开始多余快乐。学习新技术,他也比不上年轻人。运气好的话,他可以转产品、管理或做业务,运气不好的话,还得继续码代码,毕竟要养家糊口。从一家公司换到另一家公司……

“如果”

评论

JAVA线程间通信的几种方式

今天在群里面看到一个很有意思的面试题:
“编写两个线程,一个线程打印1~25,另一个线程打印字母A~Z,打印顺序为12A34B56C……5152Z,要求使用线程间的通信。”
这是一道非常好的面试题,非常能彰显被面者关于多线程的功力,一下子就勾起了我的兴趣。这里抛砖引玉,给出7种想到的解法。

1. 第一种解法,包含多种小的不同实现方式,但一个共同点就是靠一个共享变量来做控制

a. 利用最基本的synchronizednotifywait

评论