简介:分布式事务基于可靠消息最终一致性的实现方案,既然是可靠消息,则要求MQ必须支持事务管理,这样才能保证业务前后一致性。

一、最大努力通知

TCC分段提交适用分布式架构中对一致性、实时性要求较高的业务场景,在实际业务中也存在实时性比较低的业务,例如常见的短信通知,客户端消息,运营体系更新等业务,这时候为了减轻核心流程的复杂度和压力,可以采取最大努力通知方式实现柔性事务的管理。

例如常见的第三方支付业务中,本地业务和支付端业务处理完成之后都会生成消息通知,基本流程如下:

  • 本地业务预处理完成之后;
  • 请求第三方支付服务;
  • 支付操作成功对该账号发送消息;
  • 支付服务回调本地业务;
  • 本地业务生成系统通知消息;

上述流程的消息场景中有一些基础特点,在核心业务处理完成之后,发送消息通知,允许失败,在指定时间段内或者指定重试次数之后,允许消息丢失情况存在,即消息的不可靠性。

在实际的支付系统中,启动每日对账校验时会对当日的流水做校验,如果发现支付流水有未完成的流程,会有状态弥补,后续可以继续处理,这种手段在对账中很常用。

二、可靠消息

分布式事务基于可靠消息最终一致性的实现方案,既然是可靠消息,则要求MQ必须支持事务管理,这样才能保证业务前后一致性。

1、RocketMQ事务消息

RocketMQ在4.3版中开始支持分布式事务消息,采用2PC的思想来实现了提交事务消息,同时增加一个补偿逻辑来处理二阶段超时或者失败的消息,如下图所示:

上图说明了事务消息的大致方案,其中分为两个流程:正常事务消息的发送及提交、事务消息的补偿流程。

1.1 发送及提交

(1)发送消息(half消息,即发送但不被消费);

(2)服务端响应消息写入结果;

(3)根据发送结果执行本地事务,如果写入失败,此时half消息对业务不可见,本地逻辑不执行;

(4) 根据本地事务状态执行Commit或者Rollback(Commit操作生成消息索引,消息对消费者可见)

1.1 补偿流程

(1)对没有Commit/Rollback的事务消息(pending状态的消息),从服务端发起一次“回查”;

(2)Producer收到回查消息,检查回查消息对应的本地事务的状态;

(3)根据本地事务状态,重新Commit或者Rollback;

其中,补偿阶段用于解决消息Commit或者Rollback发生超时或者失败的情况。

1.3 设计原理

在RocketMQ事务消息的主要流程中,一阶段的消息如何对用户不可见。其中,事务消息相对普通消息最大的特点就是一阶段发送的消息对用户是不可见的。那么,如何做到写入消息但是对用户不可见呢?RocketMQ事务消息的做法是:如果消息是half消息,将备份原消息的主题与消息消费队列,然后改变主题为RMQ_SYS_TRANS_HALF_TOPIC。由于消费组未订阅该主题,故消费端无法消费half类型的消息,然后RocketMQ会开启一个定时任务,从Topic为RMQ_SYS_TRANS_HALF_TOPIC中拉取消息进行消费,根据生产者组获取一个服务提供者发送回查事务状态请求,根据事务状态来决定是提交或回滚消息。

2、最终一致性

基于上述RocketMQ事务消息可靠性的特点,即可以实现某类业务下事务的最终一致性。消息发送一致性是指产生消息的业务动作与消息发送一致,也就是说如果业务操作成功,那么由这个业务操作所产生的异步消息一定要发送出去,否则就业务失败回滚,消息也会丢弃。

流程基本如下:

  • 发送half事务消息,无法被消费;
  • 本地业务代码逻辑处理完成;
  • 发送确认消息,标识该消息可以消费;
  • 如果消息生产方异常,取消整体动作;

该流程主要针对消息生产方,在实际开发中,消息的消费方也一样很难处理,要保证最终一致性,必然会面对一个问题,消费方异常,消息不断的重试,可能存在部分业务处理成功,部分业务处理失败的情况,这时候就要解决服务接口的幂等性问题。

三、幂等接口

1、幂等简介

编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。就是说,一次和多次请求某一个资源会产生同样的作用影响。

在复杂的异步流程中,尤其注意失败重试问题,通常支付流程中,每次接口被请求,对每一步数据更新的操作,都会前置一步状态查询的流程,用来判断下一步的数据更新是否该执行。

2、幂等接口

在系统服务接口请求中,任何明确的接口响应,例如失败或成功,这样业务流程都好处理,但是例如支付场景如果请求超时,如何判断服务的结果状态:客户端请求超时,本地服务超时,请求支付超时,支付回调超时,客户端响应超时等,或者基于MQ的不断重试机制,在部分业务异常状态下,始终没有返回成功,则消息会一直重试。

这就需要设计流程化的状态管理,尤其在消息重试机制下,很少会再次对重试的业务接口使用重度的事务控制,有些业务被执行完毕,只需要判断一个状态,下次消息重试跳过即可,只需要把未处理的业务补偿处理即可,在重试机制下,在部分业务没有全部执行成功之前,消息会一直重试,直到最终全部完成。

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/data-manage-parent
GitEE·地址
https://gitee.com/cicadasmile/data-manage-parent

原文链接:https://developer.aliyun.com/article/771735?

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

架构设计 | 基于消息中间件,图解柔性事务一致性相关推荐

  1. 事务超时时间无效_架构设计 | 基于消息中间件,图解柔性事务一致性

    简介:分布式事务基于可靠消息最终一致性的实现方案,既然是可靠消息,则要求MQ必须支持事务管理,这样才能保证业务前后一致性. 一.最大努力通知 TCC分段提交适用分布式架构中对一致性.实时性要求较高的业 ...

  2. 架构设计 | 基于Seata中间件,微服务模式下事务管理

    源码地址:GitHub·点这里 || GitEE·点这里 一.Seata简介 1.Seata组件 Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata将为用 ...

  3. 项目体系架构设计——基于Spark平台的协同过滤实时电影推荐系统项目系列博客(四)

    系列文章目录 初识推荐系统--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(一) 利用用户行为数据--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二) 项目主要效果展示--基 ...

  4. 架构设计 | 基于电商交易流程,图解TCC事务分段提交

    本文源码:GitHub·点这里 || GitEE·点这里 一.场景案例简介 1.场景描述 分布式事务在业务系统中是十分常见的,最经典的场景就是电商架构中的交易业务,如图: 客户端通过请求订单服务,执行 ...

  5. 问题 seata_架构设计 | 基于Seata中间件,微服务模式下事务管理

    一.Seata简介 1.Seata组件 Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata将为用户提供了AT.TCC.SAGA.XA事务模式,为用户打造一 ...

  6. druid seata 配置_架构设计 | 基于Seata中间件,微服务模式下事务管理

    一.Seata简介 1.Seata组件 Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata将为用户提供了AT.TCC.SAGA.XA事务模式,为用户打造一 ...

  7. 基于消息中间件解决分布式事务的开源框架Myth

    基于消息中间件的解决分布式事务框架:https://github.com/yu199195/myth 1.rpc框架支持 : dubbo,motan,springcloud. 2.消息中间件支持 : ...

  8. 如何基于消息中间件实现分布式事务?万字长文给你答案!!

    写在前面 最近小伙伴们的要求越来越高,学完设计模式学高并发,学完高并发又想学Java8新特性,学完Java8新特性又要学Spring,学着Spring又让我整理一篇关于分布式事务的文章,而且还提出了要 ...

  9. .NET应用架构设计—表模块模式与事务脚本模式的代码编写

    阅读目录: 1.背景介绍 2.简单介绍表模块模式.事务脚本模式 3.正确的编写表模块模式.事务脚本模式的代码 4.总结 1.背景介绍 要想正确的设计系统架构就必须能正确的搞懂每个架构模式的用意,而不是 ...

最新文章

  1. 多核时代,并行编程为何“臭名昭著”?
  2. Water Research:南科大夏雨+唐圆圆-台风对深圳沿海微塑料和微塑圈的影响
  3. 宏基因组理论教程7挖掘微生物组生物标记
  4. 简明 Python 编程规范
  5. python正则匹配ip地址_Python正则表达式匹配和提取IP地址
  6. day14(xml 编写及解析)
  7. 不同网段Linux通过路由表,Linux服务器架设---《路由表配置,实现不同网段不同网卡之间的ping...
  8. springboot整合mybatis 使用HikariCP连接池
  9. ZBrush中的Clip剪切笔刷怎么快速运用
  10. idea使用svn拉取项目代码_使用 IDEA 搭建 Hadoop3.1.1 项目
  11. python中构造函数可以重载吗_python中的函数重载了吗?
  12. MySQL数据库搜题_智慧树知到_MySQL数据库设计与应用_搜题公众号
  13. iOS开源项目周报0302
  14. 06. 重建二叉树(C++版本)
  15. 对飞行前请求的响应未通过访问控制检查:它没有http ok状态。_HTTP 缓存
  16. 量化交易零基础入门教程
  17. 个人网站性能优化经历(6)网站安全方面优化
  18. hyper-v开启与关闭
  19. Android 手机录制wav格式音频文件实现
  20. 滤波电容的原理到底是什么???

热门文章

  1. 又一个神器!只需一行代码,纯文本秒变Markdown
  2. 『爬虫四步走』手把手教你使用Python抓取并存储网页数据!
  3. 人脸识别(二)——训练分类器的补充说明
  4. java 泛型机制_java中的泛型机制
  5. 颈椎前路caspar撑开器_82岁女性神经根型颈椎病,你该怎么办?手术还是不手术?...
  6. 【干货特供】dotNet core 应用部署至 centos(超详解附截图)
  7. mysql ---- 官网的测试数据库
  8. golang rpc demo
  9. CentOS下安装Hbase
  10. Hadoop的伪分布式安装