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

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

产生原因

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

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

发布方解决方案

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

.net core 的CAP框架

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

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

cap机制.jpg

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

阿里的RocketMq

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

来源阿里云.png
提交mq半事务
半事务消息成功
确认mq事务
回查事务
回滚mq事务

有以下几种情况

1.下图是完美成功情况

rocketmq.jpg

2.下图是 消息发送方没有通知到位的情况

rocketmq1.jpg

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

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

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

订阅方解决方案

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

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

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

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

3. 幂等性问题

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

  1. 根据业务状态判断,比如订单支付完成后重复推送根据完成状态忽略掉重复那条
  2. 执行业务逻辑前查询该消息是否被执行过,因为重复推送消息的消息id必然是一样的,可以根据这个消息id进行判定。
  3. 针对资源型数据,订阅会接收整个资源数据的实体,直接更新进数据库,此时需要有个更新时间,比对数据库这条数据的更新时间,只更新最新的。

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

CAP框架

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

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


cap机制 received.jpg

RocketMq

订阅消息有两种方式:

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

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

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

总结

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容