无法启动分布式事务的解决方法_分布式消息事务解决方案选型详解

分布式消息事务解决方案选型详解

微服务的普及,使用队列处理服务之间通信成为一种潮流,利用队列消息解耦系统不可避免的会出现数据不一致问题。

产生原因

发布方问题:运行的系统无法避免的存在单点故障问题,保存本地事务和推送队列无论是哪个先执行都无法保证这两个一定都执行完成,先保存本地事务,服务发生故障,消息没推送,反之同理。

订阅方问题:消费收到消息后,执行过程中发生错误或宕机,导致没执行成功。

发布方解决方案

选出两种比较简单的并且不同体系的产品来对比(阿里的RockMq/.net core的CAP框架),先了解下两种方案的实现过程

.net core 的CAP框架

首先,在你项目运行时候会在你项目指定得数据库生成一张表(cap.published)这张表是用来存储要发送消息的日志。消息有三个状态(Scheduled,Succeeded,Failed),启动程序时候同时还会启动一个监听程序,隔几分钟把表中Failed的消息重新发送。

我用下订单来举个详细例子

edfe242ad3d65c44c0472620ac8feccf.png

这种设计方式相对于2PC/TCC来说,复杂性降低了一个级别,而且支持多种数据库和消息队列,扩展性极强,我觉得缺点应该是依赖数据库,发布消息需要插入日志消息到数据库,受限于单机数据库的瓶颈,如果分库分表还要处理这块,要么就得在数据库层面做分库分表。CAP文档

阿里的RocketMq

Rocketmq的功能十分强大,有普通消息,定时消息,全局/局部顺序消息以及事务消息,在阿里云可以直接买服务来使用。RocketMq的事务采用了TCC模式(Try-Confirm-Cancel)

242078e984b2a1450d4cd4bcb9e9d08b.png
提交mq半事务半事务消息成功确认mq事务回查事务回滚mq事务

可以简单理解为下图内容 【我(消息发送方)和 大佬(rocketmq服务)的聊天记录】

a3ee48c64964507cc4d408ddbc7da6c7.png

1.完美成功情况

2.消息发送方宕机情况

32949a3d9401d8509d4837001b339688.png

3.消息发送方本地事务失败情况

可以上阿里云搜Rocketmq查看该产品使用手册。

阿里的RocketMq 与 CAP 使用架构场景分析

CAP适合于发送队列消息与业务在同一个服务的场景,而中台架构就不适合,因为中台架构分基础服务和业务中台,队列一般在业务中台跟业务挂钩,有一个订单基础服务,但有N个应用中台都是调用这个订单基础服务存储订单数据,每个中台都相当于一个应用,逻辑可能差异很大,更倾向于在中台决定推不推送消息和推什么消息,这种情况下CAP就完全不适合。

订阅方解决方案

1. 系统突然崩溃导致丢失

系统的瞬态故障产生的问题,重试便可以解决

2. 程序出现bug导致一直重试一直失败

这种情况重试是解决不了问题的,需要开发人员做好PlanB,重试N次不成功便执行PlanB。

3. 幂等性问题

发送端监听重复推送导致的问题,有两种方案可以解决。

  1. 根据业务状态判断,比如订单支付完成后重复推送根据完成状态忽略掉重复那条
  2. 执行业务逻辑前查询该消息是否被执行过,因为重复推送消息的消息id必然是一样的,可以根据这个消息id进行判定。

回到选中的两大框架的消费端

CAP框架

同发送端一样,在你项目运行时候会在你项目指定得数据库生成一张表(cap.received)这张表是用来存储消费的消息日志。消息有三个状态(Scheduled,Succeeded,Failed),启动程序时候同时还会启动一个监听程序,隔几分钟把表中Failed的消息重消费。

发送端演示下单,消费端就来个扣库存的。

df97ce6ce04a77ddbb781209f82c9c94.png
RocketMq

订阅消息有两种方式:

1.通过http拉取(注意 官方的SDK的http请求性能很差,建议最好自己写)

2.开启tcp监听获取(注意 .net的TCP监听获取消息的SDK至今没有Linux版本--2019年12月13)

获取消息需要在代码里进行ack确认

总结

CAP框架:功能单一,使用简单,.net体系的可自行扩展,适合自治微服务架构。

RocketMq:功能丰富,维护简单,稳定性强,但使用还需要自己做相关开发,使用成本高,对.net支持不太好,适合中台服务。


作者:Carson_dotnet
链接:https://www.jianshu.com/p/f90ce421893e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值