ddd-cqrs-axon_运行Axon Server-Java中的CQRS和事件源

ddd-cqrs-axon

重要要点

  • CQRS和事件源要求对命令,查询和事件的存储(事件存储)和传输(消息传递中心)提供特定的基础结构支持。
  • 可以通过结合使用现有的中间件工具(例如Kafka和AMQP)来支持用于支持CQRS和事件源的多种消息传递模式,但是诸如Axon Server的多合一解决方案是一种有吸引力的选择。
  • 最好以一种使安装本身“无状态”的方式来完成Axon Server的启动和运行,这意味着我们将配置分为固定的和特定于环境的设置。
  • Axon Server企业版增加了运行群集的功能,但是单个节点可以具有非常特定的身份,但所提供的服务有很大差异。 这会影响部署策略。
  • 向Axon Server添加访问控制(令牌和用户帐户)和TLS非常容易。

Java中的CQRS和事件源

现代的消息传递和事件驱动的应用程序具有与传统企业应用程序明显不同的要求。 明确的迹象是,重点已从保证传递单个消息(传递的责任主要在中间件上)转移到“智能端点和愚蠢的管道”,这取决于应用程序来监视传递和守时。 结果是,消息传递基础结构上的服务质量要求更多地是关于吞吐量而不是传递保证。 消息没有达到预期的目标是发送者和接收者都必须解决的问题,因为它们从根本上负责受此类故障影响的业务需求,并且最有能力确定适当的响应。

发生的另一个变化是存储和处理能力的价格稳定下降的直接结果,以及将这些资源分配给应用程序组件的灵活性提高了:命令查询责任隔离(简称为CQRS)和事件源。 在您的应用程序环境中,没有一个组件来管理“黄金记录”以进行更新和查询,而是将这两个职责分开,并提供了多个查询源。 Command分量(通常是等式的低频分量)可以针对验证和存储进行优化。 然后,使用事件向企业的其他成员宣布经过验证的更改,其中(多个)查询组件使用它们来构建优化的模型。 前向高速缓存和批处理副本的使用增加,是一个预警信号,表明迫切需要此体系结构模式,并且具有可重播事件存储的查询模型将此处所需的许多解决方案形式化。 通过使用导致事件的事件序列定义实体的当前状态,事件搜索在此方面取得了进步。 这意味着,我们不保留记录的可更新存储,而是使用仅追加事件存储,从而使我们可以使用Write-Once语义并同时获得不中断的审核跟踪。

为了支持这些更改,我们将传统组件(即数据库)和面向消息的中间件(具有所需功能)以及新的,专用的基础结构组件进行了扩展。 在Java和Kotlin软件开发领域,开源Axon框架提供了CQRS和事件源范例的领先实现,但它仅为应用程序的各个模块提供了解决方案。 如果将应用程序放在一个整体的安装中,这无疑是提供最快的方式启动并运行以进行未开发的开发工作,则无法利用其对更分布式架构的支持似乎是一种浪费。 就其本身而言,基于Axon的应用程序的体系结构很容易被拆分或“勒死”,这已成为更流行的术语。 那么问题是我们如何支持消息传递和事件存储实现。

基于CQRS的应用程序的体系结构

典型的CQRS应用程序具有交换命令和事件的组件,并具有通过显式命令处理的聚合的持久性以及优化的查询模型 并根据报告汇总状态的事件进行构建。 可以在RDBMS存储层或NoSQL文档组件上构建此设置中的聚合持久层,并且框架核心中包括基于标准JPA / JDBC的存储库。 存储查询模型也是如此。

可以使用大多数标准消息传递组件来解决用于交换消息的通信,但是使用模式确实支持针对不同场景的特定实现。 只要我们可以确保没有消息丢失,我们就可以使用几乎任何现代消息解决方案作为发布-订阅模式,因为我们希望查询模型能够忠实地表示聚合状态。 对于命令,如果仅要确保我们可以检测到命令处理程序的不可用,就需要将基本的单向消息传递扩展为请求-应答模式。 其他答复可能是汇总的结果状态,或者如果否决了更新,则是详细的验证失败报告。 在查询方面,简单的请求-应答模式不足以实现分布式微服务体系结构。 我们还希望查看分散收集和先进先出模式,以及通过持续更新获得的流式结果。

对于事件源,聚合持久性层可以替换为Write-Once-Read-Many层,该层捕获命令产生的所有事件,并为特定聚合提供重播支持,这些重播可用于查询模型,从而使我们使用内存存储重新实现它们,或者在我们怀疑数据不一致时提供重新同步。 快照的使用是一个有用的改进,因此我们可以避免重放可能很长的更改历史记录,并且Axon Framework为聚合提供了标准的快照实现。

现在,如果我们看一下在应用程序的基础结构组件中收集的内容,则需要满足以下条件:

  • 状态存储的聚合和查询模型的“标准”持久性实现。
  • 事件源聚合的一次写入多次读取持久性解决方案。
  • 消息传递解决方案,用于:
    • 请求答复
    • 至少一次发布发布-订阅
    • 重播发布-订阅
    • 散布聚集
    • 请求流式答复

Axon框架提供了附加模块,以集成各种开源产品,例如用于事件分发的基于Kafka和基于AMQP的解决方案。 但是,毫不奇怪,AxonIQ自己的Axon Server也可以用作一体式解决方案。 本系列文章介绍了如何进行安装和运行,从简单的本地安装开始,然后逐步进行基于Docker的安装(包括docker-compose和Kubernetes)以及“云中”的VM。

设置测试

首先,让我们考虑一个小程序,以演示我们要添加到体系结构中的组件。 我们将使用Spring Boot来简化配置,Axon有一个Spring Boot启动器,它将扫描我们使用的注释。 作为第一个迭代,我们将其保留在一个简单的应用程序中,该应用程序发送导致事件的命令。 为此,我们需要处理以下命令:

@CommandHandler
    public void processCommand(TestCommand cmd) {
        log.info("handleCommand(): src = '{}', msg = '{}'.",
                 cmd.getSrc(), cmd.getMsg());

        final String eventMsg = cmd.getSrc() + " says: " + cmd.getMsg();
        eventGateway.publish(new TestEvent(eventMsg));
    }

这里的命令和事件是简单的值对象,第一个指定源和一条消息,其他仅一条消息。 同一类还定义了将接收上面发布的事件的事件处理程序:

@EventHandler
    public void processEvent(TestEvent evt) {
        log.info("handleEvent(): msg = '{}'.", evt.getMsg());
    }

要完成此应用程序,我们需要添加一个发送命令的“启动器”:

@Bean
    public CommandLineRunner getRunner(CommandGateway gwy) {
        return (args) -> {
            gwy.send(new TestCommand("getRunner", "Hi there!"));
            SpringApplication.exit(ctx);
        };
    }

对于第

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值