自己建设网站赚钱,优化推广网站推荐,太原网站制作电话,从零搭建企业网站大家好#xff0c;我是 方圆。最近在读《微服务架构设计模式》#xff0c;开始的时候我非常的好奇#xff0c;因为在我印象中#xff0c;设计模式是常说的那23种设计模式#xff0c;而微服务的设计模式又是什么呢#xff1f;这个问题也留给大家#xff0c;在文末我会附上…大家好我是 方圆。最近在读《微服务架构设计模式》开始的时候我非常的好奇因为在我印象中设计模式是常说的那23种设计模式而微服务的设计模式又是什么呢这个问题也留给大家在文末我会附上我对这个问题的理解。本次文章的内容主要是工作中对微服务设计模式的应用希望能对大家有所启发。
事务发件箱模式 事务发件箱模式将消息保存在数据库 “发件箱”表 作为事务的一部分 policy 为处理投保的微服务以投保事务为例 如上图所示在投保过程中有4步操作注意持久化结算任务TaskA的操作这个过程便是事务发件箱模式的体现为什么说它是事务发件箱模式呢
Task 表中持久化的消息任务最终会被发送到 MQ 中所以它是发件箱持久化 Task 记录的操作被包含在事务中所以称它为事务发件箱
Task 记录中保存的消息体是通过另一个服务 service-job 轮询扫描初始化状态的任务并将其发送到 MQ 的发送成功后任务修改为完成状态这种方式被称为事务性发件箱模式中的轮询发布数据模式。
这种设计模式有一个弊端随着数据量不断增大经常轮询数据库可能造成昂贵的开销。在我们的系统中采用了两种措施进行优化
分库分表以空间换时间避免单表数据量过大造成的开销将完成状态的任务进行“数据结转”的设计任务先保存在 Task 表中被执行完成后被归档到 TaskRecord 表中
此外还有一种更加高效但是开发稍复杂的方式拖尾数据库日志模式。
拖尾数据库日志模式 数据库的每次更新都对应着一条数据库事务日志通过事务日志挖掘器读取事务日志并将每条与消息有关的记录发送给消息代理开源框架可参考Github: debezium可以将MySQL的binlog读取到Kafka中但是这种方法的弊端是需要在开发上做一些努力因为需要监听数据库事务日志和调用数据库底层相关的API。
相信“邮递员”
工程实践中还有一种没有采用事务发件箱模式来保证数据一致性的方法在事务中先持久化完成状态的任务随后直接将消息发送给消息队列如果消息发送失败捕获异常并将任务修改成初始化状态随后依赖 service-job 服务进行补偿即将初始化状态的任务发送给 MQ。我们还是以投保的过程为例如下代码所示
// 1. 持久化保单数据
savePolicy();
// 2. 持久化保单明细数据
savePolicyDetail();
// 3. RPC 调用投保接口
rpcPolicy();
// 4. 持久化完成状态的任务任务中记录了要发送给MQ的消息体
int num insertTask(TaskStatus.COMPLETE);
// 5. 如果插入成功了借助线程池发送消息
if (num 1) {threadPoolExecutor.execute(() - {try {mq.send(task.info);} catch(Exception e) {// 发送失败抛出异常修改任务状态为初始化状态依赖 service-job 服务进行补偿updateTask(TaskStatus.INIT);}});
}这种设计模式默认认为MQ集群始终是高可用的我将这种设计模式命名为相信“邮递员”。在生产实践中因为有MQ运维团队在保障MQ集群的高可用所以这种设计模式也是比较稳定的。 在投退保流程中涉及不同数据库的修改操作如保单的持久化、保单状态的修改以及相关结算的推送要保证这个过程中的数据一致性那么便不能再依赖ACID本地事务而是需要使用跨服务的 Saga 设计模式来维护数据一致性。下面我们来介绍两种分别是协同式Saga和编排式Saga。 Saga 通过使用异步消息来驱动一系列本地事务来维护多个服务之间的数据一致性。 协同式Saga
我们先带着 Saga 的概念来看一下投保的流程 在这个过程中Saga的决策和执行顺序分布在Saga的每一个参与方中并且通过消息交换的方式进行沟通一个Saga的参与方执行完触发另一个Saga执行保证数据一致性这种方式被称为协同式Saga。
这种设计模式的优劣如下
优势比较简单服务间松耦合弊端比较难理解因为它没有一个地方定义了Saga的执行流程Saga的处理逻辑分布在不同的服务中需要根据代码触发的任务去整理整个流程 为什么没有采用XA来实现分布式事务 XA采用两阶段提交协议实现分布式事务在事务中的所有参与者都成功时提交有失败时便回滚。要使用该模式一方面要求所有的事务参与者数据库或消息代理满足XA标准另一方面它本质上是同步的进程间通讯同步的通讯机制有一个弊端它会降低分布式系统的可用性假如分布式系统中每个服务的可用性为99%如果服务与服务之间是同步调用的方式服务必须从另外一个服务获取响应后才能返回它的客户端调用那么分布式系统的可用性为各个服务可用性的乘积随着同步交互服务的增加可用性会随之降低最大化可用性的方式应该最小化系统间的同步操作量。所以一般互联网公司很少采用强一致性的设计而是采用最终一致性设计银行可能会使用到强一致性。此外XA实现分布式事务需要依赖事务的协调者如Seata实现起来相比于上述方式复杂。 编排式Saga
Saga 的另一种实现方式是编排式编排式 Saga 需要事务的协调者DTM全局事务发起人将整个全局事务的编排信息包括每个步骤的正向操作和反向补偿操作定义好之后提交给事务协调者DTM协调者按步骤异步执行Saga逻辑。
如果投保流程使用编排式Saga的话投保成功的过程如下 编排式Saga的事务定义执行步骤非常灵活假如我们要在投保失败的情况下做取消结算的补偿逻辑的话可以自行定义图示如下 这种设计模式的优劣如下
优势能够集中流程控制、易于扩展和服务间松耦合如果服务之间的依赖关系复杂且业务流程经常变动使用编排式Saga是合适的 弊端引入协调者增加了开发复杂性扩展学习DTM开源项目文档 现在我们回到文章开篇的问题微服务架构设计模式与我们常说的设计模式的区别是什么 我们常说的设计模式是面向对象的设计模式它的解决方案元素是类而微服务设计模式是站在更高维度即系统架构层面的设计模式它面向的对象是系统中各个服务解决方案也由相互协作的服务构成的。 巨人的肩膀
《微服务架构设计模式》第 1 - 4 章