DDD - 六边形架构和CQRS架构

简介: DDD - 六边形架构和CQRS架构


1. 六边形架构

六边形架构又称为端口-适配器,这个名字更容器理解。六边形架构将系统分为内部(内部六边形)和外部,内部代表了应用的业务逻辑,外部代表应用的驱动逻辑、基础设施或其他应用。内部通过端口和外部系统通信,端口代表了一定协议,以API呈现。一个端口可能对应多个外部系统,不同的外部系统需要使用不同的适配器,适配器负责对协议进行转换。这样就使得应用程序能够以一致的方式被用户、程序、自动化测试、批处理脚本所驱动,并且,可以在与实际运行的设备和数据库相隔离的情况下开发和测试。

六边形架构的核心理念是:应用是通过端口与外部进行交互的

在下图的六边形架构中,红圈内的核心业务逻辑(应用程序和领域模型)与外部资源(包括 APP、Web 应用以及数据库资源等)完全隔离,仅通过适配器进行交互。它解决了业务逻辑与用户界面的代码交错问题,很好地实现了前后端分离。六边形架构各层的依赖关系是由外向内依赖的。

六边形架构将系统分为内六边形和外六边形两层,这两层的职能划分如下:

  • 红圈内的六边形实现应用的核心业务逻辑;
  • 外六边形完成外部应用、驱动和基础资源等的交互和访问,对前端应用以 API 主动适配的方式提供服务,对基础资源以依赖倒置被动适配的方式实现资源访问。

六边形架构的一个端口可能对应多个外部系统,不同的外部系统也可能会使用不同的适配器,由适配器负责协议转换。这就使得应用程序能够以一致的方式被用户、程序、自动化测试和批处理脚本使用。

2. CQRS

2.1 什么是CQRS

CQRS,作为一种战术办法,是实现DDD建模领域的最佳途径之一。事实上,它就是因为这个目标而诞生在这个世界上。

CQRS本身只是一个读写分离的架构思想,全称是:Command Query Responsibility Segregation,即命令查询职责分离,表示在架构层面,将一个系统分为写入(命令)和查询两部分。一个命令表示一种意图,表示命令系统做什么修改,命令的执行结果通常不需要返回;一个查询表示向系统查询数据并返回

CQRS架构中,另外一个重要的概念就是事件,事件表示命令操作领域中的聚合根,然后聚合根的状态发生变化后产生的事件。

2.2 采用CQRS架构的一个前提

由于CQRS架构的一致性模型为最终一致性,所以,你的系统要接受查询到的数据可能不是最新的,而是有几个毫秒的延迟。之所以会有这个前提,是因为CQRS架构考虑到,作为一个多用户同时访问的互联网应用,当在高并发修改数据的情况下,比如秒杀、12306购票等场景,用户UI上看到的数据总是旧的。比如你秒杀时提交订单前看到库存还大于0,但是当你提交订单时,系统提示你宝贝卖完了。这个就说明,在这种高并发修改同一资源的情况下,任何人看到的数据总是Stale的,即旧的。

2.3 实现方式

CQRS作为一种架构思想,可以有多种实现方式:

  • 最常见的CQRS架构是数据库的读写分离
  • 系统底层存储不分离,但是上层逻辑代码分离
  • 系统底层存储分离,C 端采用 Event Sourcing 的技术,在 EventStore 中存储事件;Q 端存储对象的最新状态,用于提供查询支持;

Event Sourcing - 事件溯源:

  • 不保存对象的最新状态,而是保存对象产生的所有事件;
  • 通过事件溯源(Event Sourcing, ES)得到对象最新状态。

2.4 CQRS的适用场景

  1. 当我们的应用的写模型和读模型差别比较大时;
  2. 当我们希望实践DDD时;因为CQRS架构可以让我们实现领域模型不受任何ORM框架带来的对象和数据库的阻抗失衡的影响;
  3. 当我们希望对系统的查询性能和写入性能分开进行优化时,尤其是读/写比非常高的系统,CQ分离是必须的;
  4. 当我们希望我们的系统同时满足高并发的写、高并发的读的时候;因为CQRS架构可以做到C端最大化的写,Q端非常方便的提供可扩展的读模型。

这里我主要分享的CQRS架构是上面第3种实现方式,也就是上图所画的架构。在我心目中,只有第三种才是真正意义上的CQRS架构。

2.5 CQRS架构的数据流

C 端的命令的执行流程

客户端如(MVC Controller)发送命令通知系统做修改:

  1. 发送命令到分布式MQ;
  2. 然后命令的订阅者处理命令;
  3. 订阅者内部根据不同的命令调用不同的 Command Handler 进行处理;
  4. Command Handler 内部根据命令所指定的聚合根 ID 从 In-Memory 内存中直接获取聚合根对象的引用,然后操作聚合根对象;
  5. 聚合根对象状态发生变化并产生事件;
  6. 框架负责自动持久化事件到 Event Storage(简称EventStore);
  7. 框架负责将事件发布到 Event MQ;
  8. Event 订阅者订阅事件,然后调用对应的 Event Handler 进行处理,如更新 Data Storage(保存了聚合根的最新状态,通常叫读库,ReadDB)。

Q端的查询的执行流程

客户端如(MVC Controller)发出查询请求系统返回数据:

  1. 调用轻薄的 Query Service,传如 Query DTO;
  2. Query Service 从读库进行查询并返回结果。

读库可以有很多种,依据我们的业务场景来选择:比如关系型DB、分布式缓存等NoSQL、搜索引擎,etc。

2.6 CQRS\ES - 架构演进

相关文章
|
3月前
|
消息中间件 前端开发 测试技术
DDD - 分层架构:有效降低层与层之间的依赖
DDD - 分层架构:有效降低层与层之间的依赖
|
7月前
|
设计模式 架构师 程序员
DDD洋葱架构才是 yyds!阿里大牛手记(DDD)领域驱动设计应对之道
虽然身为架构师,设计一个高质量的架构依然是复杂与困难的。 简单来说,动用大量的资源只为了一套优质的三高架构并不正确,而是该在了解当前业务现状的情况下,创造出灵活、可维护、健硕能成长的。
|
8月前
|
存储 监控 测试技术
构建可扩展的应用:六边形架构详解与实践
构建可扩展的应用:六边形架构详解与实践
226 0
|
12月前
|
消息中间件 JavaScript 小程序
领域驱动设计(DDD)的几种典型架构介绍
领域驱动设计(DDD)的几种典型架构介绍
|
12月前
|
存储 JSON 自然语言处理
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合(下)
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合
|
12月前
|
存储 搜索推荐 NoSQL
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合(上)
「领域驱动设计」DDD,六边形架构,洋葱架构,整洁架构和CQRS的整合
|
10天前
|
敏捷开发 监控 数据管理
构建高效微服务架构的五大关键策略
【4月更文挑战第20天】在当今软件开发领域,微服务架构已经成为一种流行的设计模式,它允许开发团队以灵活、可扩展的方式构建应用程序。本文将探讨构建高效微服务架构的五大关键策略,包括服务划分、通信机制、数据管理、安全性考虑以及监控与日志。这些策略对于确保系统的可靠性、可维护性和性能至关重要。
|
10天前
|
消息中间件 监控 持续交付
构建高效微服务架构:后端开发的进阶之路
【4月更文挑战第20天】 随着现代软件开发的复杂性日益增加,传统的单体应用已难以满足快速迭代和灵活部署的需求。微服务架构作为一种新兴的分布式系统设计方式,以其独立部署、易于扩展和维护的特点,成为解决这一问题的关键。本文将深入探讨微服务的核心概念、设计原则以及在后端开发实践中如何构建一个高效的微服务架构。我们将从服务划分、通信机制、数据一致性、服务发现与注册等方面入手,提供一系列实用的策略和建议,帮助开发者优化后端系统的性能和可维护性。
|
5天前
|
消息中间件 负载均衡 持续交付
构建高效微服务架构:后端开发者的终极指南
【4月更文挑战第25天】在当今软件工程领域,微服务架构已经成为实现可扩展、灵活且容错的系统的首选模式。本文将探讨如何从零开始构建一个高效的微服务系统,涵盖关键组件的选择、通信机制、数据管理以及持续集成和部署策略。通过深入分析与案例研究,我们旨在为后端开发者提供一个全面的微服务实践指南,帮助他们在构建现代化应用时做出明智的架构决策。
|
5天前
|
消息中间件 持续交付 数据库
构建高效可靠的微服务架构:策略与实践
【4月更文挑战第25天】 随着现代软件开发的复杂性日益增加,传统的单体应用已难以满足快速迭代和灵活部署的需求。本文深入探讨了如何构建一个高效且可靠的微服务架构,包括关键的设计原则、技术选型以及实践中的挑战和应对策略。通过分析多个成功案例,我们总结了一系列最佳实践,并提出了一套可量化的性能优化方法。文章不仅为开发者提供了具体的技术指导,同时也强调了团队协作和持续学习在微服务转型过程中的重要性。