`最近一个项目用的技术比较新,整理一些相关的知识,主要是领域设计与saga分布式事务处理,还有引申到cqrs与基于api优先开发。网上的知识比较杂,所以所这些相关的汇总一下,红色粗体是自己的思考。`
是无法嵌
## `1. 微服务与DDD`
https://www.cnblogs.com/davenkin/p/6612656.html
- `两者默契`
`在[微服务](https://martinfowler.com/articles/microservices.html)(Microservices)架构实践中,人们大量地借用了DDD中的概念和技术,比如一个微服务应该对应DDD中的一个限界上下文(Bounded Context);在微服务设计中应该首先识别出DDD中的聚合根(Aggregate Root);还有在微服务之间集成时采用DDD中的防腐层(Anti-Corruption Layer, ACL);我们甚至可以说DDD和微服务有着天生的默契。`
- `领域事件`
`在DDD中有一条原则:一个业务用例对应一个事务,一个事务对应一个聚合根,也即在一次事务中,只能对一个聚合根进行操作。实际应用中,我们经常发现一个用例需要修改多个聚合根的情况,故引入领域事件。领域事件作为已经发生过的历史数据,在建模时应该将其创建为不可变的特殊值对象。存在多种方式用于发布领域事件,其中“在聚合中临时保存领域事件”的方式是值得推崇的。为了避免事件重复带来的问题,最好的方式是将事件的消费方创建为幂等的。`
1. `解耦微服务(限界上下文)`
2. `帮助我们深入理解领域模型`
3. `提供审计和报告的数据来源`
4. `迈向[事件]等`
- `事务性`
`如果JTA不是你的选项,那么可以考虑采用事件表的方式。这种方式首先将事件保存到聚合根所在的数据库中,由于事件表和聚合根表同属一个数据库,整个过程只需要一个本地事务就能完成。然后,在一个单独的后台任务中读取事件表中未发布的事件,再将事件发布到消息中间件中。`
- `持久化`
`其实对于DDD中的聚合根来说,NoSQL是相比于关系型数据库更合适的选择,比如用MongoDB的Document保存聚合根便是种很自然的方式。但是多数NoSQL是不支持ACID的,也就是说不能保证聚合更新和事件发布之间的原子性。还好,关系型数据库也在向NoSQL方向发展,比如新版本的PostgreSQL([版本9.4](https://www.postgresql.org/docs/9.4/static/datatype-json.html))和MySQL([版本5.7](https://dev.mysql.com/doc/refman/5.7/en/json.html))已经能够提供具备NoSQL特征的JSON存储和基于JSON的查询。此时,我们可以考虑将聚合根序列化成JSON格式的数据进行保存,从而避免了使用重量级的ORM工具,又可以在多个数据之间保证ACID,何乐而不为?`
- `值对象`
`聚合根:独立存在的对象,是代表某个限界上下文中的一个高内聚的整体概念。他的生命周期是其所属上下文中所承担的职责的周期。`
`实体:无法独立存在,是聚合根的一部分,生命周期由所属的聚合根掌控。`
`值对象:可以独立存在,但是无法进行自我管理,可以描述任何聚合根/实体,无生命周期的概念,也可以理解为永生(无限生命周期)。`
> `1.把值对象中的属性作为所属实体/聚合根的数据列来存储。`
>
> `缺点:会导致数据表列数较多,在一个数据页存储的数据量变少,影响数据库表的使用性能。`
>
> `2.把整个值对象序列化后作为所属实体/聚合根的数据列来存储。`
>
> `缺点:出现大数据长度的列,页会导致在一个数据页存储的数据量变少,影响数据库表的使用性能。另外无法直接通过SQL来查询值对象的属性,需要自定义做反序列化操作。`
>
> `3.如果是ORM类的框架,那么建立一个基类通过protected的标识列来委派这个唯一标识,但是在实际运用过程中是感觉不到这个存在的。`
> `4.如果不是ORM框架或者本身框架支持,那么可以通过无主键的方式存入到数据表中。`
>
> `缺点:是无法嵌TAO模型`
>
`聚合根与实体比较好理解,比如订单与订单中的项目。值对象比如就是聚合根的相关的属性的集合,比如地址对象,一般是拆开细节属性,与所属聚合根或者实体的属性一起存贮。`
`**不过我在考虑用hash当ID,另存一个表。hash来自值对象的每一个值,值对象有hash方法,值对象属性都相同则hash相同,只存一条记录。**`
`另外,如果采用ddd方式,由于专注于对邻域对象的操作,命令,以及事件处理,这些特点必然从系统层面进行分离,集中处理邻域对象的变化,于是有了CQRS。以往只是数据库层面的读写分离,发展到了系统代码层面的分离了。`
## `2. 分布式事务一致性`
`https://www.cnblogs.com/skyesx/p/9697817.html`
`https://cloud.tencent.com/developer/article/1545301`
`这个理论就不说了,ACID,BASE,CAP..,重点提一个saga模式。`
`从简单到复杂,可以选择多种方式:`
> `基于消息实现的事务:适用于分布式事务的提交或回滚只取决于事务发起方的业务需求,其他数据源的数据变更跟随发起方进行的业务场景。本地提交事务,发消息即可。`
> `但是基于消息实现的事务并不能解决所有的业务场景,例如以下场景:某笔订单完成时,同时扣掉用户的现金。`
>
> `这里事务发起方是管理订单库的服务,但对整个事务是否提交并不能只由订单服务决定,因为还要确保用户有足够的钱,才能完成这笔交易,而这个信息在管理现金的服务里。这里我们可以引入基于补偿实现的事务,本地事务不提交,远程调用,根据结果提交或者回滚。若不能使用基于消息队列的最终一致性事务,那么可以优先考虑使用基于补偿的事务形态。`
>
> `阿里GTS/fescar本质上也是这补偿的编程模型,只不过补偿代码自动生成,无需业务干预,同时接管应用数据源,禁止业务修改处于全局事务状态中的记录。因此,其关于读场景的适用性,可参考补偿。但其在写的适用场景由于引入了全局事务时的写锁,其写适用性介于 TCC以及补偿之间 。`
### `TCC实现的事务`
`每个业务实现try,confirm,cancle,本地事务都提交,但业务上是保留资源,比如冻结金融并不真正扣除。`
`比基于补偿实现的事务的流程要复杂,同时开发的工作量也更多。TCC实际上是最为复杂的一种情况,其能处理所有的业务场景,但无论出于性能上的考虑,还是开发复杂度上的考虑,都应该尽量避免该类事务。`
`很多金融核心以上的业务(比如在渠道层、产品层、集成层的系统),这些系统的特点是最终一致即可、流程多、流程长、还可能要调用其它公司的服务(如金融网络)。这是如果每个服务都开发 Try、Confirm、Cancel 三个方法成本高。如果事务中有其它公司的服务,也无法要求其它公司的服务也遵循 TCC 这种开发模式。同时流程长,事务边界太长会影响性能。`
### `Saga(*Eventuate* *Tram* *Saga*)`
`核心以上的业务系统可以采用补偿事务,补偿事务处理方面在30年前就提出了 Saga 理论,随着微服务的发展,近些年才逐步受到大家的关注。目前业界比较也公认 Saga 是作为长事务的解决方案。`
`Saga有两个方式:Orchestration(有中心协调者)和Choreography(无中心协调者)。`
- 1. `有中心协调者的Saga方式需要可能存在协调者本身失败的单点风险,但是能够方便减轻业务应用的开发量,能够形成Saga框架,由框架自己管理流程前进和回退。`
- 2. `Choreography需要使用事件概念,引入事件概念可能会增加业务应用开发的难度,除非业务应用时遵循DDD领域事件开发方式。这样,事务处理就是领域事件的处理方式了。
`
`最近一个项目中是用Eventuate Tram saga 的 Orchestration处理事务,也用Eventuate Tram框架处理领域事件。可以对比一下guava的eventBus。`
`https://developer.aliyun.com/article/725370`
`服务需要使用库来发送和接收消息。一种方法是使用消息代理的客户端库,但是直接使用这样的库有几个问题:`
- - `客户端库将发布消息的业务逻辑耦合到消息代理API。`
- - `消息代理的客户端库通常是非常底层的,需要多行代码才能发送或接收消息。作为开发人员,你不希望重复编写类似的代码。`
- - `客户端库通常只提供发送和接收消息的基本机制,不支持更高级别的交互方式。`
`更好的方法是使用更高级别的库或框架来隐藏底层的细节,并直接支持更高级别的交互方式。为简单起见,本书中的示例使用了我的Eventuate Tram框架。它有一个简单易用的API,可以隐藏使用消息代理的复杂性。除了用于发送和接收消息的API之外,Eventuate Tram还支持更高级别的交互方式,例如异步请求/响应和领域事件发布。`
`使用开源Eventuate框架,这个框架是为事务性消息、事件溯源和Saga量身定做的。之所以选择,是因为它与依赖注入和Spring框架不同,对于微服务架构所需的许多功能,目前开发者社区还没有广泛采用的框架。如果没有Eventuate Tram框架,许多演示代码必须直接使用底层消息传递API,这会使它们变得更加复杂并且会模糊重要的概念。或者使用一个没有被广泛采用的框架,这也会引起批评。`
`相反,这些演示代码使用Eventuate Tram框架,该框架具有隐藏实现细节的简单易懂的API。你可以在应用程序中使用这些框架。或者,你可以研究Eventuate Tram框架并自己重新实现这些概念。`
`Eventuate Tram还实现了两个重要机制:`
- - `**事务性消息机制:**它将消息作为数据库事务的一部分发布。`
- - `**重复消息检测机制:**Eventuate Tram支持消息的接收方检测并丢弃重复消息,这对于确保接收方只准确处理消息一次至关重要。
`
`Eventuate Tram框架为Java应用程序实现事务性消息。它提供了一个相对底层的API,用于以事务方式发送和接收消息。它还提供了更高级别的API,用于发布和使用领域事件以及发送和处理命令式消息。`
### `方法选择`
```
单机事务》基于消息的事务》基于补偿的事务》TCC事务
```
`因SAGA事务的形态需要配合较为明显的前端业务交互变更,个人建议在单一事务执行过程较长、存在较多子事务,并且无法使用基于消息的事务形态时使用。`
## `3. 开发角度`
`分为:存储层(respository),领域对象层(domain),服务层,接口web层。`
#### `领域对象层`
`https://www.jianshu.com/p/4551c0248289`
`我们的核心实体(Entity)和值对象(Value Object)应该在Domain层,不要把Entity的属性和行为分离到Domain和Service两层中去实现,即所谓的贫血模型,事实证明这样的实现方式会造成很大的维护问题。作为元模型中元素之一的实体本身就应该包含针对自身的行为定义。`
`一般返回对实体操作后,返回ResultWithDomainEvents,即包含结果,又包含事件。比如修改后,返回包含【实体】与【包含dto对象的事件】的组合结果。`
#### `服务层`
`通常持有持久化对象Repository,与事件发布对象EventPublisher。比如处理实体修改的操作,包括:`
- `根据id从存贮层得到实体`
- `对实体执行实体自身的操作`
- `对操作后返回的ResultWithDomainEvents进行处理,包括保存修改后的实体与发布事件操作。`
`服务层要么不返回结果,比如修改不返回,只是void。或者返回dto对象。`
`此外,还包含event处理包(领域事件处理用),command处理包(saga命令处理用)。`
#### `API`
`https://www.jdon.com/53930`
`遵循API优先方法,我们在开始编码之前先指定一个API。通过API描述语言,团队可以进行协作而无需执行任何操作。`
`API层包含领域事件对象,以及request对象,返回的vo对象。`
`使用openApi标准的yml接口规范文档,使用swagger-codegen-maven-plugin的maven插件,同时引用上面的对象,可以生成java API的代码框架。`
分享到:
相关推荐
本套笔记全面覆盖了SpringCloud微服务架构的关键知识点,从理论到实践,帮助读者深入了解并掌握微服务设计原则和SpringCloud的实现方式,对于想要在微服务领域深化学习的Java开发者来说是一份宝贵的资料。
近年来,“微服务”这一概念迅速成为了软件开发领域的热门话题。微服务不仅改变了传统的软件架构方式,还引领了一种全新的开发模式。本文旨在深入探讨微服务的概念、起源及其在Golang中的应用。 ##### 1.1 什么是...
读书笔记:微服务与DDD《实现领域驱动设计》示例代码
读书笔记:基于 ASP.NET Core 的领域驱动设计微服务架构实现方案
读书笔记:基于DDD领域驱动设计并支持SaaS平台的微服务框架
读书笔记:基于领域驱动设计模式开发一个售后补偿微服务。
- **解决的问题**:探讨 Spring Cloud 在微服务领域中的作用。 - **架构及其核心组件**:讲解 Spring Cloud 的架构设计及其核心组件。 - **Spring Cloud 与 Dubbo 对比**:比较两者在微服务解决方案上的异同。 -...
《2023软件设计师笔记》是一份针对软件设计领域的深度学习资料,旨在帮助读者全面理解和掌握软件设计的精髓。这份笔记涵盖了软件设计的基础概念、关键技术和最新趋势,是提升软件设计技能的理想参考资料。 首先,...
读书笔记:领域驱动设计——实战落地代码基于单体项目拆分【基于SpringBootCloud的微服务项目】
读书笔记:基于微服务架构的物料管理系统实现前后端分离前端包括Web端、移动端业务服务基于领域驱动设计实现
在“软件设计师笔记和试题”这个压缩包中,包含了丰富的学习资源,主要针对的是软件设计师这一职业资格认证的备考人员。下面将详细解读其中的知识点和试题内容。 首先,"知识点总结"这部分很可能是对软件设计领域...
【标题】:“狂神说java系列笔记”涵盖了Java的基础、Web开发、SSM框架以及微服务等关键领域,是一套全面深入的Java学习资源。它旨在帮助初学者和进阶者掌握Java编程语言的核心概念,以及在实际项目开发中的应用。 ...
《软件考试系统架构设计师学习笔记(整理版)》是一份详尽的学习资料,主要针对的是软件考试中的系统架构设计师这一专业领域。这份笔记包含了自2008年以来的历年试题,是备考者全面掌握该考试内容的重要参考资料。...
在微服务领域,Spring Boot简化了应用的启动和配置,Spring Cloud则提供了服务发现、配置中心、负载均衡等功能。 2. **Spring Boot**:Spring Boot为快速开发提供了便利,通过预设默认配置,可以快速搭建一个运行...
在软件设计领域,个人的笔记往往是积累知识、提升技能的重要途径。这份笔记涵盖了软件设计师日常工作中可能会遇到的各种关键知识点,旨在帮助设计师在项目开发中更好地规划、设计和实施软件系统。 一、软件设计基础...
在微服务领域,Clojure因其简洁的语法、强大的并发处理能力和对数据的天然表示能力而备受青睐。 Pedestal是Clojure社区中用于构建Web服务的一个框架。它提供了HTTP服务器、路由、中间件和API生成等功能,非常适合...
《软件设计师笔记资料》是一个专为准备软件设计师考试的学习者精心整理的压缩包资源,它涵盖了软件设计领域的诸多核心知识点,对于想要通过软件设计师考试的同学来说,无疑是一份宝贵的参考资料。下面,我们将深入...
### 软考系统架构设计师考试笔记核心知识点详解 #### 一、系统规划 ##### 1.1 项目的提出与选择 - **知识点**: 项目的提出与选择是系统规划的第一步,主要目的是根据市场需求和技术发展趋势,选定合适的项目,并...
Go语言以其快速编译、垃圾回收、C-like语法和内置并发机制而受到开发者们的喜爱,尤其在云计算和微服务领域广泛应用。 笔记中的内容可能包括以下几个主要部分: 1. **基础语法**:介绍Go语言的基础结构,如变量...