目录
三、管理事务边界:微服务架构中推崇打破事务边界实现数据弱一致性
一、管理服务的依赖关系:构建无环依赖关系
依赖关系主要有三种基本表现形式:直接依赖、间接依赖和循环依赖,我们需要根据无环依赖原则知道在系统设计中不应该存在循环依赖,三种依赖关系如图所示:
我们需要消除循环依赖,基本思路是通过在两个相互依赖的组件之间添加中间层,变循环依赖为间接依赖。有三种方式可以做到这一点,分别是上移、下移和回调。
我们以具体例子讲解下,如下图是一个循环依赖,User对象可以创建Order对象并保存Order对象列表,而Order对象需要用到User对象来进行打折discount信息计算Order金额,显然User对象和Order对象循环依赖。
1.上移切入点:交互部分抽离
思想试将两个相互依赖的组件中的交互部分抽象出来形成一个新的组件,而新的组件包含原来两个组件的引用,即将循环依赖关系剥离出来并上升到一个更高层次的组件中。
对User对象和Order对象循环依赖进行上移,引入一个新组件Mediator,并提供一个payOrder()方法对循环关系进行剥离,方法中使用User和Order作为参数,实现Order中根据User的打折信息进行金额计算的业务逻辑。
2.下移切入点:依赖关系转移重构
将依赖关系进行重构,重构抽象一个Calculator组件专门包含打折信息和金额计算,该Calculator由User创建,并注入到Order的pay方法中。
3.回调切入点:接口或抽象类
回调本质上就是一种双向调用模式。在面向对象的语言中,回调通常通过接口或抽象类的方式来实现。
我们抽象出一个Calculator接口用于封装金额计算逻辑,该接口与Order处于同一个层次,User实现该接口,这样一来,原关系转变为了间接依赖。通过依赖注入机制,很容易实现Order和User之间的有效交互。
二、管理服务数据
任何业务都需要使用某个数据容器作为持久化的机制或数据处理的媒介,所谓的数据容器,不仅仅指关系型数据库,而是泛指包括消息队列、搜索引擎索引以及各种NoSQL在内的数据媒介。
1.微服务中的数据管理策略
集中式数据管理方式有明显有点,可由专业的DBA或系统管理员来规划、实施以及优化。
但微服务崇尚把数据嵌入到微服务内部,这样就涉及数据相关的关系型数据库、各种NoSQL存储、搜索引擎索引等将成为微服务自身的一部分。如下图,将数据完全嵌入到微服务看上去很完美,但实际存在两大问题:(1)大多数微服务而言,为每个服务匹配独立的数据存储容器显然是一种浪费,因为多数服务比较简单;(2)对于由很多微服务构成的系统而言,搜索引擎等工具同样存在很多实例,会给运维带来巨大挑战。
一个微服务并不一定需要独立去包含自身所需要的数据,也可以采用集中式的数据管理方式在一定程度上实现数据独立性,对于数据媒介而言可以设置命名空间的概念,可以针对每个微服务规划专属于它的表空间,从而在逻辑上与其他微服务进行隔离。
注意,对于一些业务比较独立且数据访问存在瓶颈的微服务而言,在设计时就将数据进行物理隔离自然是最佳实践。
2.数据管理尝试策略:CQRS模式及与领域驱动相结合
CQRS模式。即命令查询的责任分离,是一种架构体系模式,能够改变模型状态的命令和模型状态的查询实现分离。
数据操作的基本表现为CRUD,可以简单分为读R和写CUD,对应可分为Query模式和Command模式。
在设计接口时,如果可能,应该尽量使接口单一化,严格保证方法的行为是命令或查询,这样一来,查询方法不会改变对象的状态,没有副作用,而会改变对象状态的方法不应有返回值。
将其与领域事件结合起来使用,可构建高度低耦合系统,也是目前互联网系统中非常常见的一种架构设计方法,即某一个微服务负责产生和维护数据。这些数据以事件作为表现形式并通过消息传递系统发送到搜索引擎中,而另一个微服务则专门负责查询搜索引擎中的数据进行进一步处理。
使用CQRS模式实际上与数据去中心化是一种互补的关系,把各个微服务所依赖的数据统一存储到专门用于查询的中央创库是一种最佳实践。
三、管理事务边界:微服务架构中推崇打破事务边界实现数据弱一致性
在微服务架构中,传统分布式事务并不是实现数据一致性的最佳选择,在微服务架构中,我们推崇的是打破事务的边界,实现数据的弱一致性,微服务架构里面建议“兜底”思维,即不管实现方案是否完美,最后都要有一个备选方案,备选方案不一定满足日常业务场景,但当出现异常情况时,可通过备选完成正常业务的闭环。具体在后面进行分析。
参考书籍、文献和资料:
【1】郑天民. 微服务设计原理与架构. 北京:人民邮电出版社,2018.