微服务的兴起以及现代软件架构对可扩展性、灵活性和可维护性的需求导致开发人员接受各种设计模式。
站在用户的角度思考问题,与客户深入沟通,找到白云网站设计与白云网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:网站制作、做网站、企业官网、英文网站、手机端网站、网站推广、域名注册、虚拟空间、企业邮箱。业务覆盖白云地区。
近年来备受关注的一种模式是命令查询职责分离 (CQRS) 模式。CQRS 特别适合命令(改变状态)和查询(读取状态)之间有明显区别的系统。在本文中,我们将深入研究 CQRS 并了解如何使用 Spring 微服务来实现它。
命令查询职责分离(CQRS)是一种架构模式,建议将数据修改操作(命令)与数据检索操作(查询)分离。这种分离允许开发专门的模型来查询和更新数据,从而增强应用程序的清晰度和可扩展性。
CQRS 的核心目标是通过确保每个任务负责单个操作(命令或查询,但绝不会同时负责两者)来简化任务。
CQRS 并不是一个全新的概念。它的根源可以追溯到 CQS(命令查询分离),这是 Eiffel 编程语言的创建者 Bertrand Meyer 推广的一项原则。虽然 CQS 主要是关于方法——声明方法应该执行命令或回答查询,但 CQRS 将这一原则扩展到应用程序的架构级别,建议不同的架构组件处理命令和查询。
微服务架构的兴起放大了 CQRS 的必要性。在分布式系统中,服务通常需要自治和高度解耦,CQRS 提供了一条清晰的路径。每个微服务都可以采用 CQRS 模式,确保其处理命令和查询的内部机制从其他服务中抽象出来。这也与领域驱动设计(DDD)非常吻合,其中领域事件可以触发不同微服务中的命令。
虽然 CQRS 提供了许多好处,但它也面临着挑战:
Spring 生态系统拥有丰富的工具和框架,非常适合在微服务环境中实现 CQRS 模式。
第一步是建立一个基本的 Spring Boot 项目。如果您是 Spring Boot 新手,您可以使用Spring Initializr轻松初始化您的项目。基本依赖项包括 Spring Web、Spring Data JPA 以及您喜欢的任何数据库连接器。
在基于 Spring 的 CQRS 系统中,命令表示更改某些状态的意图,命令处理程序处理这些命令。
示例命令:
public class CreateUserCommand {
private final String userId;
private final String username;
// Constructor, getters, and other methods...
}
对于每个命令,都定义了相应的命令处理程序。该处理程序包含处理命令的实际逻辑:
@Service
public class CreateUserCommandHandler implements CommandHandler {
@Autowired
private UserRepository userRepository;
@Override
public void handle(CreateUserCommand command) {
User user = new User(command.getUserId(), command.getUsername());
userRepository.save(user);
}
}
在领域驱动设计(DDD)的背景下,状态突变通常发生在聚合上。这些聚合可确保在保留任何更改之前遵守所有域规则。
类似地,查询表示读取某些状态的请求,查询处理程序处理这些请求。
查询示例:
public class GetUserByIdQuery {
private final String userId;
// Constructor, getters, and other methods...
}
对应的查询处理程序:
@Service
public class GetUserByIdQueryHandler implements QueryHandler {
@Autowired
private UserRepository userRepository;
@Override
public User handle(GetUserByIdQuery query) {
return userRepository.findById(query.getUserId()).orElse(null);
}
}
虽然 CQRS 提供了隔离机制,但可以使用事件源来简化命令和查询之间状态的维护。Axon 框架是一种有助于使用 Spring 实现 CQRS 和事件溯源的流行框架。
对于 Axon,事件在命令处理后发布。这些事件可以被持久化,然后用于重新创建聚合的状态。它还有助于保持查询端与命令端同步。
鉴于微服务的分布式特性,在服务之间实现异步通信通常是有益的。Apache Kafka 可以集成到 Spring 生态系统中,以实现强大的事件驱动架构,这在 CQRS 设置中特别有用。
命令端产生的事件可以推送到Kafka主题中,查询端可以使用这些事件来更新自己的数据存储。这确保了命令端和查询端之间的解耦,使系统更具弹性和可扩展性。
虽然 CQRS 专注于分离命令和查询职责,但事件溯源可确保应用程序状态的每次更改都被捕获在事件对象中,并按照它们应用于同一聚合的顺序存储。这种方法允许您重建过去的状态,并且与 CQRS 结合使用时特别有利。
事件溯源是关于持久化域事件而不是状态本身。这些事件捕获状态转换。通过重放它们,可以重建聚合的当前状态。
例如,您将存储所有交易(例如存款和取款等事件),而不是存储银行帐户的当前余额。通过重播这些事件可以得出当前余额。
CQRS 和事件溯源通过以下方式相互补充:
如前所述,Axon 框架提供了一种在 Spring 应用程序中实现 CQRS 和事件源的无缝方法:
聚合和事件处理: 在 Axon 中,聚合负责命令处理和事件生成。处理命令后,它们应用导致状态更改的事件。
@Aggregate
public 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 和事件溯源可以提供巨大的好处,但它们也具有复杂性。意识到这些挑战将确保更明智、更顺利的实施。
架构复杂性: CQRS 和事件源向系统引入了额外的层和组件,例如事件存储、命令和事件总线以及同步机制。
学习曲线: 对于刚接触这些模式的团队,将有一个学习阶段。从传统的基于 CRUD 的系统的概念转变可能具有挑战性。
最终一致性: 鉴于命令和查询模型的隔离性质,通常会为了最终一致性而牺牲即时一致性。这意味着在命令端所做的更改反映在查询端之前可能会有延迟。
事件排序: 确保事件按照生成的顺序进行处理,尤其是在分布式系统中,可能很棘手,但对于保持一致的状态至关重要。
随着时间的推移,事件的结构或语义可能会发生变化,从而导致以下挑战:
存储注意事项: 由于存储所有事件,事件存储可能会快速增长,从而导致存储成本增加和潜在的性能问题。
重播持续时间: 通过重播长期历史事件来重建系统状态可能非常耗时,会影响系统恢复和初始化时间。
将使用 CQRS 和事件源的系统与不遵循这些模式的外部系统集成可能具有挑战性,特别是在数据同步和事务管理方面。
粒度决策: 决定应用 CQRS 和事件溯源的粒度至关重要。在微观层面上实施它们可能会导致过于复杂化,而过于广泛地实施可能会削弱好处。
域复杂性: 这些模式对于简单域来说可能有点过分了。它们更适合复杂的领域,其好处超过了实施和维护成本。
虽然有像 Axon 和框架这样的工具支持 CQRS 和事件溯源,但它们可能并不总是适合所有场景。可能需要自定义实现,这会增加项目的复杂性和持续时间。
CQRS 提供了一种独特的方式来扩展和组织微服务。当与 Spring 的生态系统结合时,它可以提供强大的工具包来构建健壮、可扩展和可维护的系统。然而,与所有架构决策一样,必须权衡利弊并确保它适合您的特定用例。
网页题目:SpringBoot与CQRS的完美结合:构建高效、可扩展的应用程序
文章转载:http://www.shufengxianlan.com/qtweb/news22/154572.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联