在微服务架构盛行的当下,领域驱动设计(DDD)也得到了崭新的发展。在DDD中包含了聚合、领域事件等核心概念,也需要引入CQRS、事件溯源等架构模式。对于开发人员而言,如何简单而高效的实现这些核心概念和架构模式是一大痛点。一方面,这些概念和模式晦涩难懂,无法直接用简单的技术体系就能实现。另一方面,业界关于如何实现DDD应用程序也没有统一的开发规范。
Axon框架的诞生为开发人员解决这些痛点问题提供了即插即用的解决方案。今天的内容,我们就将围绕Axon框架的各项功能展开详细的讨论。
Axon框架与DDD
在具体介绍Axon框架之前,让我们先简单回顾几个DDD的核心概念。我们知道在一个DDD限界上下文中,内部是以聚合、实体和值对象为代表的一组领域模型对象,而针对领域模型中状态的变化,聚合会生成一系列的领域事件。领域事件可以通过事件存储器进行保存,也可以发布到其他限界上下文中。另一方面,在领域模型对象的外部是应用服务和资源库。应用服务分别命令服务和查询服务,是CQRS架构模式的具体应用。而资源库则完成与各种持久化媒介的集成,如下图所示。
自2010年诞生以来,Axon框架在过去几年中有了很大的发展。围绕上图中的各个DDD核心概念,除了为开发人员提供了一个内核框架之外,还提供了一个服务器选项,其中包括一个事件存储器和一个事件路由器。Axon内核框架与服务器相结合,对实现CQRS和时间溯源架构模式所需的复杂基础设施问题进行了高度抽象。基于Axon框架的应用架构如下图所示。
在上图中,我们看到了一组Axon技术组件,包括领域模型、资源库、命令处理程序和事件处理程序等,这些组件分别与DDD中的领域模型对象、资源库、命令服务、领域事件概念相对应。我们也注意到在Axon中专门提供了一个事件存储器组件用来存储领域事件。
同时,我们在上图中还看到了一个事件总线组件,这是Axon中内置的总线中的一种。基于这些技术组件,开发人员可以不需要从零开始实现CQRS架构模式和事件溯源机制,从而只关注业务逻辑的实现过程。接下来,让我们从Axon的整体架构开始展开,对这些技术组件做进一步的分析。
Axon技术组件
Axon整体架构
从整体架构进行分析,Axon框架由三大部分组成,包括领域模型(Domain Model)组件、分派模型(Dispatch Model)组件和Axon服务器(Server)。
其中:
- 领域模型组件:这部分组件是Axon的核心组件,用来帮助开发人员构建以DDD、事件溯源和CQRS为中心的应用程序。
- 分派模型组件:这部分组件用来提供针对领域模型的逻辑基础架构,包括支持对命令和查询操作的路由和协调,这些操作在Axon中同样被用来处理领域模型状态。
- 服务器:Axon本身也提供了一个服务器组件,该组件用来支持前面提到的领域和分派模型的物理基础架构。
上图进一步展示了Axon框架为我们提供的这些技术组件的详细组成,可以看到Axon框架也提供了一个外部对接组件,可以和MongoDB、Kafka等外部基础设施组件进行交互,从而满足不同场景下的定制化需求。
从上图中,我们可以看到一组DDD中的核心,包括领域模型对象、领域事件、资源库、命令处理程序、事件处理程序,以及通过命令和事件组合在一起的其他组件。这些组件是实现普通面向领域应用程序所需要具备的。Axon对这些组件也做了一定的封装和抽象,从而帮助开发人员更好的实现领域模型。
另一方面,我们也看到了一组前面没有介绍过的组件,例如专门针对事件溯源过程的事件溯源处理程序、包括命令总线、事件总线以及专门针对领域事件的存储库。这些组件主要就是Axon框架我们提供的领域分派组件,除了这里的命令总线、事件总线之外,还有查询总线,开发人员直接使用即可。
基于这些技术组件,Axon框架的整体工作流程如下图所示。
同时,在上图中,我们也可以看出,位于上半部分的组件能够改变应用程序的状态,而位于下半部分的组件则读取或查询应用程序的状态。显然,在这种明确的分离中,我们也嵌入了CQRS架构模式。
围绕图X,可以看到我们发起的命令操作通过命令总线传递到命令处理程序。因为命令操作会引起领域模型状态的变化,所以就需要生成领域事件。领域事件同样通过领域总线进行传播,并被不同的事件处理程序进行处理。最终,领域事件及其处理结果被保存下来,供查询操作获取最新的领域状态。
Axon服务器
Axon服务器是Axon为开发人员提供了一个可视化服务器组件,包括一批即插即用的功能组件,例如:
- 专门用来存储事件的事件存储库,基于H2内存数据库进行实现
- 内置对领域事件的路由机制
- 提供简洁明了的用户界面控制台
- 提供对系统数据的备份和版本控制
- 提供对系统行为的监控和度量机制
- 提供对系统访问的安全控制机制
- 提供对系统运行的集群管理机制
Axon服务器在物理上就是一个Spring Boot应用程序,并作为常规的JAR文件进行发布,我们可以从Axon的官方网站www.axoniq.io上进行下载。
当我们使用java -jar axonserver.jar命令启动Axon服务器,并在浏览器中访问http://localhost:8024/,可以得到如下图所示的用户操作界面。
可以看到这个控制台提供监控和管理Axon服务器的一组功能,包括设置、搜索、概览、用户等常规功能,包括命令、查询等于CQRS直接相关的浏览界面,也包括用于与第三方组件进行集成的插件界面。
Axon应用方式
如果你已经开发了一个DDD应用程序,那么想要引入Axon框架,就需要对现有系统进行重构。重构的对象主要是两个方面,一个是领域模型,一个是应用服务。
对于领域模型而言,针对聚合对象,我们需要引入命令处理程序来重构对命令的处理过程。而当领域事件被发送之后,我们同样需要对聚合中如何处理领域事件的过程进行重构,并引入全新的事件溯源组件。在这个组件中,我们就可以对聚合的状态做相应的调整。对于领域事件而言,Axon内置了完整的事件存储器和事件发布和消费机制。
应用服务是我们重构的重点对象之一,因为在Axon中,对命令服务和查询服务所应该具备的操作做了明确的定义,我们需要引入命令总线和查询总线来分派命令和查询操作,并使用命令处理程序和查询处理程序来分别处理命令和查询对象。在引入了Axon框架之后,我们需要对原有的命令服务和查询服务的代码组织方式和功能实现过程都做出相应的调整,才能符合基于Axon中CQRS架构的开发需求。
如果你正在开发一个DDD应用程序,那么引入Axon框架是一个明智的选择。Axon能够帮助开发人员显著简化开发过程和难度。Axon之所以能做到这一点,是因为它内置了一组即插即用的领域模型组件和分派模型组件,前者包括命令处理程序、查询处理程序、事件处理程序等,而后者则包含命令总线、查询总线和事件总线等。除此之外,Axon还专门提供了一个服务器组件用来提供可视化的管理界面。今天的内容对Axon中的这些技术组件都做了详细的展开,并在最后总结了该框架的具体应用方式。