当前位置:首页 > 科技  > 软件

从CRUD到CQRS:使用Spring微服务转变你的架构策略

来源: 责编: 时间:2023-10-16 17:10:05 167观看
导读介绍微服务的兴起以及现代软件架构对可扩展性、灵活性和可维护性的需求,促使开发者采用各种设计模式。近年来,命令查询责任分离(Command Query Responsibility Segregation,CQRS)模式在实践中获得大量推广。CQRS特别适用于

介绍

cos28资讯网——每日最新资讯28at.com

微服务的兴起以及现代软件架构对可扩展性、灵活性和可维护性的需求,促使开发者采用各种设计模式。近年来,命令查询责任分离(Command Query Responsibility Segregation,CQRS)模式在实践中获得大量推广。CQRS特别适用于那些命令(用于修改状态)和查询(用于读取状态)之间存在明显区别的系统。本文将深入探讨CQRS,并演示如何使用Spring微服务进行实现。cos28资讯网——每日最新资讯28at.com

什么是 CQRS?

命令查询职责分离(CQRS)是一种架构模式,建议将数据修改操作(命令)与数据检索操作(查询)分离。这种分离允许为查询和更新数据开发专门的模型,提高应用程序的清晰度和可扩展性。cos28资讯网——每日最新资讯28at.com

CQRS 的核心目标是通过确保每个任务负责单个操作(命令或查询,但绝不会同时负责两者)来简化任务。cos28资讯网——每日最新资讯28at.com

起源和演进

CQRS并不是一个全新的概念。它的根源可以追溯到CQS(Command Query Separation,命令查询分离)原则,该原则由Eiffel编程语言的创建者Bertrand Meyer推广。尽管CQS主要关注方法层面,即一个方法应该执行命令或回答查询,但CQRS将这一原则扩展到了应用程序的架构层面,建议使用独立的架构组件处理命令和查询。cos28资讯网——每日最新资讯28at.com

为什么使用CQRS?

  • 可扩展性:CQRS允许水平扩展,可以根据需求部署多个命令或查询服务的实例。读操作和写操作可以独立进行扩展,优化资源利用率。
  • 灵活性:命令和查询之间职责明确,意味着开发者可以针对每个操作使用最适合的持久化机制、策略和优化方式。例如,虽然关系数据库可能用于事务性命令操作,但非规范化的视图存储甚至全文搜索引擎可以用于处理查询。
  • 可维护性:良好实现的CQRS模式简化了代码库。通过为读操作和写操作分别建立模型,开发者可以专注于每个操作的具体内容,而不会被无关的问题分散注意力。这种分离有利于开发出更清晰、更易于维护和扩展的代码。
  • 增强安全性:CQRS本质上促进了更好的安全实践。通过分离命令和查询操作,可以更容易地对写操作进行严格的验证和授权检查,同时优化读操作以提高性能。

CQRS在微服务中的应用

在分布式系统中,服务通常需要具有自治性和高度解耦,CQRS提供了一个清晰的路径。每个微服务都可以采用CQRS模式,确保它处理命令和查询的内部细节与其他服务分离。这也与领域驱动设计(DDD)非常契合,其中领域事件可以触发不同微服务中的命令操作。cos28资讯网——每日最新资讯28at.com

潜在的问题

尽管CQRS带来了许多好处,但也存在一些挑战:cos28资讯网——每日最新资讯28at.com

  • 复杂性增加:引入CQRS可能会增加开销,特别是在读操作和写操作之间的区别不明显的系统中。并不总是需要将每个读操作和写操作分离,这样做可能会导致不必要的复杂性增加。
  • 一致性:考虑到写存储和读存储可能是不同的,确保它们之间的数据一致性可能具有挑战性,特别是在分布式系统中。

使用Spring微服务实现CQRS

Spring生态系统中丰富的工具和框架非常适合在微服务环境中实现CQRS模式。cos28资讯网——每日最新资讯28at.com

新建一个Spring Boot项目

第一步是创建一个基本的Spring Boot项目。如果你是第一次使用Spring Boot,可以使用Spring Initializr初始化项目。可以根据自己偏好引入一些必需的依赖项包括Spring Web、Spring Data JPA、数据库连接器等。cos28资讯网——每日最新资讯28at.com

命令、命令处理器和聚合

在基于Spring的CQRS系统中,命令表示改变某个状态的意图,而命令处理器则用于处理这些命令。cos28资讯网——每日最新资讯28at.com

命令示例如下:cos28资讯网——每日最新资讯28at.com

public class CreateUserCommand {    private final String userId;    private final String username;    // 构造函数, getters,以及其他方法...}

对于每个命令,都需要定义了相应的命令处理器。该处理器需要包含处理命令的实际逻辑,如下:cos28资讯网——每日最新资讯28at.com

@Servicepublic class CreateUserCommandHandler implements CommandHandler<CreateUserCommand> {        @Autowired    private UserRepository userRepository;    @Override    public void handle(CreateUserCommand command) {        User user = new User(command.getUserId(), command.getUsername());        userRepository.save(user);    }}

在领域驱动设计(DDD)的上下文中,状态变更通常发生在聚合根上。这些聚合根需要遵循所有领域规则,然后在对数据变更进行持久化。cos28资讯网——每日最新资讯28at.com

查询和查询处理器

类似地,查询表示读取某些状态的请求,而查询处理器则处理这些请求。cos28资讯网——每日最新资讯28at.com

查询命令示例:cos28资讯网——每日最新资讯28at.com

public class GetUserByIdQuery {    private final String userId;    // 构造函数, getters, 以及其他方法}

对应的查询处理器:cos28资讯网——每日最新资讯28at.com

@Servicepublic class GetUserByIdQueryHandler implements QueryHandler<GetUserByIdQuery, User> {        @Autowired    private UserRepository userRepository;    @Override    public User handle(GetUserByIdQuery query) {        return userRepository.findById(query.getUserId()).orElse(null);    }}

事件溯源及Axon框架集成

尽管CQRS提供了分离的机制,但使用事件溯源可以简化在命令和查询之间维护状态的过程。Axon Framework是一个实现了CQRS和事件溯源的流行框架。cos28资讯网——每日最新资讯28at.com

在Axon中,事件在命令处理后进行发布。这些事件可以被持久化,然后用于重新创建聚合根的状态,有助于保持查询端与命令端的同步。cos28资讯网——每日最新资讯28at.com

使用Apache Kafka进行异步通信

考虑到微服务的分布式特性,实现服务之间的异步通信是非常有必要的。可以将Apache Kafka集成到Spring生态系统中,以实现强大的事件驱动架构,这在CQRS设置中尤其有用。cos28资讯网——每日最新资讯28at.com

由命令端产生的事件可以推送到Kafka的主题中,查询端可以消费这些事件来更新自己的数据存储。这确保了命令端和查询端之间的解耦,使系统更具弹性和可扩展性。cos28资讯网——每日最新资讯28at.com

事件溯源和CQRS

尽管CQRS专注于分离命令和查询的责任,但事件溯源确保将应用程序状态的每次更改捕获在事件对象中,并按照应用顺序存储在相同聚合根上。这样允许你重建过去的状态,在与CQRS结合使用时特别有优势。cos28资讯网——每日最新资讯28at.com

事件溯源的核心思想

事件溯源是一种将领域事件持久化而不是持久化状态本身的方式。这些事件捕获状态转换。通过重新播放这些事件,可以重建聚合根的当前状态。cos28资讯网——每日最新资讯28at.com

例如,可以存储银行账户的所有交易(像存款和提款这样的事件),而不是仅存储当前余额。通过重新播放这些事件,可以计算出当前余额。cos28资讯网——每日最新资讯28at.com

事件溯源的好处

  • 审计追踪:事件溯源提供了自然的更改审计日志,这对于需要追溯性和历史记录的领域非常重要。
  • 时间查询:可以确定系统在任何时间点的状态。这对于调试和理解过去的状态非常有用。
  • 事件重放:通过重新播放事件,可以重新生成面向读取的优化视图。当你想要创建新投影或重建损坏的投影时,这特别有用。

事件溯源与CQRS集成

CQRS和事件溯源是相辅相成的,表现在以下几个方面:cos28资讯网——每日最新资讯28at.com

  • 解耦:就像CQRS中的命令和查询解耦一样,通过事件溯源,事件(代表状态变化)与实际状态解耦,这促进了松散耦合的架构。
  • 可扩展性:CQRS中读操作和写操作的分离性与事件驱动系统非常契合。命令模型处理命令并生成事件,而查询模型处理查询并可以通过侦听这些事件进行更新。
  • 弹性:通过重播事件,可以在发生故障甚至迁移到全新系统时重新构建系统的状态。

使用Spring和Axon框架实现

正如之前提到的,Axon Framework为在Spring应用程序中实现CQRS和事件溯源提供了一种无缝的方案:cos28资讯网——每日最新资讯28at.com

  • 聚合根和事件处理:在Axon中,聚合根负责处理命令和生成事件。在处理完命令后,它们会应用导致状态变化的事件。
@Aggregatepublic class Account {    @AggregateIdentifier    private String accountId;    private int balance;    @CommandHandler    public void handle(WithdrawMoneyCommand cmd) {        if (cmd.getAmount() > balance) {            throw new InsufficientFundsException();        }        apply(new MoneyWithdrawnEvent(cmd.getAccountId(), cmd.getAmount()));    }    @EventSourcingHandler    public void on(MoneyWithdrawnEvent evt) {        this.balance -= evt.getAmount();    }}
  • 事件存储:Axon提供了一种存储和检索事件的机制。这些事件可以重播,以重建聚合根的状态。
  • 投影:Axon中的投影提供了CQRS的查询端。它们监听事件并更新读取优化的视图。这样,查询模型始终与最新的更改保持同步。

挑战和考虑因素

尽管CQRS和事件溯源可以带来巨大的好处,但也带来了复杂性。cos28资讯网——每日最新资讯28at.com

复杂性开销

  • 架构复杂性:CQRS和事件溯源引入了额外的层次和组件到系统中,如事件存储、命令和事件总线以及同步机制。
  • 学习曲线:对于不熟悉这些模式的团队来说,需要一个学习阶段。从传统的基于CRUD的系统转变思维可能是具有挑战性的。

数据一致性

  • 最终一致性:由于命令和查询模型的分隔性质,即时一致性常常被牺牲以换取最终一致性。这意味着在命令端进行的更改在查询端反映出来之前可能会有延迟。
  • 事件顺序:确保事件按照生成的顺序进行处理,特别是在分布式系统中,可能会很棘手,但对于维护一致的状态至关重要。

事件版本控制

随着时间的推移,事件的结构或语义可能会发生变化,从而带来以下挑战:cos28资讯网——每日最新资讯28at.com

  • 版本不匹配:处理同一事件类型的不同版本可能变得复杂。
  • 事件升级:随着事件的演变,系统必须能够将旧版本的事件升级到新版本,而不修改存储的事件。

数据存储和重放

  • 存储考虑:由于所有事件都被存储,事件存储库可能会迅速增长,导致存储成本增加和潜在的性能问题。
  • 重放持续时间:通过重放大量历史事件来重建系统状态可能耗时很长,影响系统的恢复和初始化时间。

其他系统集成

使用CQRS和事件溯源的系统与不遵循这些模式的外部系统集成可能具有挑战性,特别是在数据同步和事务管理方面。cos28资讯网——每日最新资讯28at.com

边界确定

  • 粒度决策:决定应用CQRS和事件溯源的粒度非常重要。在微观级别实施可能导致过度复杂化,而过于广泛地实施可能会削弱其好处。
  • 领域复杂性:对于简单的域来说,这些模式可能过于复杂。它们更适用于复杂的领域,其中好处超过了实施和维护成本。

工具和基础设施

虽然有像Axon这样的工具和框架支持CQRS和事件溯源,但它们可能并不完全适合所有场景。可能需要进行定制实现,这可能会增加项目的复杂性和持续时间。cos28资讯网——每日最新资讯28at.com

结论

CQRS为扩展和组织微服务提供了一种独特的方式。当与Spring生态系统结合使用时,它可以提供一个强大的工具包,用于构建健壮、可扩展和易于维护的系统。然而,就像所有架构决策一样,需要权衡利弊并确保它是否适合你的实际场景。cos28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-13617-0.html从CRUD到CQRS:使用Spring微服务转变你的架构策略

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 向量化操作简介和Pandas、Numpy示例

下一篇: 掌握这五个要点,利用IntelliJ IDEA进行前端开发

标签:
  • 热门焦点
  • 对标苹果的灵动岛 华为带来实况窗功能

    对标苹果的灵动岛 华为带来实况窗功能

    继苹果的灵动岛之后,华为也在今天正式推出了“实况窗”功能。据今天鸿蒙OS 4.0的现场演示显示,华为的实况窗可以更高效的展现出实时通知,比如锁屏上就能看到外卖、打车、银行
  • 2023年Q2用户偏好榜:12+256G版本成新主流

    2023年Q2用户偏好榜:12+256G版本成新主流

    3月份的性能榜、性价比榜和好评榜之后,就要轮到2023年的第二季度偏好榜了,上半年的新机潮已经过去,最明显的肯定就是大内存和存储的机型了,另外部分中端机也取消了屏幕塑料支架
  • 六大权益!华为8月服务日开启:手机免费贴膜、维修免人工费

    六大权益!华为8月服务日开启:手机免费贴膜、维修免人工费

    8月5日消息,一年一度的华为开发者大会2023(Together)日前在松山湖拉开帷幕,与此同时,华为8月服务日也式开启,到店可享六大专属权益。华为用户可在华为商城Ap
  • 把LangChain跑起来的三个方法

    把LangChain跑起来的三个方法

    使用LangChain开发LLM应用时,需要机器进行GLM部署,好多同学第一步就被劝退了,那么如何绕过这个步骤先学习LLM模型的应用,对Langchain进行快速上手?本片讲解3个把LangChain跑起来
  • 三万字盘点 Spring 九大核心基础功能

    三万字盘点 Spring 九大核心基础功能

    大家好,我是三友~~今天来跟大家聊一聊Spring的9大核心基础功能。话不多说,先上目录:图片友情提示,本文过长,建议收藏,嘿嘿嘿!一、资源管理资源管理是Spring的一个核心的基础功能,不
  • ESG的面子与里子

    ESG的面子与里子

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之三伏大幕拉起,各地高温预警不绝,但处于厄尔尼诺大&ldquo;烤&rdquo;之下的除了众生,还有各大企业发布的ESG报告。ESG是&ldquo;环境保
  • AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    Tenstorrent是一家由芯片行业资深人士Jim Keller领导的加拿大初创公司,专注于开发人工智能芯片,该公司周三表示,已经从现代汽车集团和三星投资基金等
  • 苹果公司要求三星和LG Display生产「无边框」OLED iPhone显示屏

    苹果公司要求三星和LG Display生产「无边框」OLED iPhone显示屏

    据 The Elec 报道,苹果已要求其供应商为未来的 iPhone 型号开发「无边框」OLED 显示面板。苹果显然已要求三星和 LG Display 开发新的 OLED 显示面
  • 外交部:美方应停止在网络安全问题上不负责任地指责他国

    外交部:美方应停止在网络安全问题上不负责任地指责他国

      中国外交部今天(16日)举行例行记者会。会上,有记者问,美国情报官员称,他们正在阻拦来自中国以及其他国家的黑客获取相关科研成果。 中方对此有何评论?对此
Top