分布式事务四_基于可靠消息的最终一致性

分布式事务四_基于可靠消息的最终一致性

更多干货


消息发送一致性(可靠消息的前提保障)

一、消息中间件的应用场景

image

  • 消息中间件在分布式系统中的主要作用:异步通讯、解耦、并发缓冲
  • 如图:通过引入消息中间件来解耦应用间(服务间)的直接调用,同时也会起到异步通讯和缓冲并发的作用

二、消息发送和投递的不可靠性

image


分布式部署环境下,需要通过网络进行通讯,就引入了数据传输的不确定性也就是CAP理论中的P(分区容错性的问题)

三、消息发送一致性

消息发送一致性:是指产生消息的业务动作与消息发送的一致。

(也就是说,如果业务操作成功,那么由这个业务操作所产生的消息一定要成功投递出去,否则就丢消息) image

四、消息发送一致性如何保障?

1. 处理方式1

/** 支付订单处理 **/
public void completeOrder() {
// 订单处理(业务操作)
orderBiz.process();
// 发送会记原始凭证消息(发送消息)
sendAccountingVoucherMsg ();
}
  1. 如果业务操作成功,执行消息发送前应用故障,消息发不出去,导致消息丢失(订单系统与会计系统的数据不一致)
  2. 如果业务操作成功,应用正常,但消息系统故障或网络故障,也会导致消息发不出去(订单系统与会计系统的数据不一致)

2. 处理方式2

/** 支付订单处理 **/
public void completeOrder() {
// 发送会记原始凭证消息(发送消息)
sendAccountingVoucherMsg ();
// 订单处理(业务操作)
orderBiz.process();
}
  1. 这种情况下,更不可控,消息发出去了,但业务可能会失败(订单系统与会计系统的数据不一致)

前面两种方式,都不能保证业务数据的一致性

五、JMS标准中的XA协议方式是否可以保障发送一致性?

JMS协议标准的API中,有很多以XA开头的接口,其实就是前面课程讲到的支持XA协议(基于两阶段提交协议)的 全局事务型接口。JMS中的XA系列接口,可以提供分布式事务支持。 但引用了XA方式的分布式事务,又会带来很多的局限:

  • 要求业务操作的资源必须支持XA协议(并不是所有资源都支持XA)
  • 两阶段提交协议的成本
  • 持久化成本等DTP模型的局限性(全局锁定,成本高,性能低)

引入XA,违背了柔性事务的初衷


六、消息发送一致性:变通的做法

image

  1. 主动方应用先把消息发给消息中间件,消息状态标记为“待确认”;
  2. 消息中间件收到消息后,把消息持久化到消息存储中,但并不向被动方应用投递消息;
  3. 消息中间件返回消息持久化结果(成功/失败),主动方应用根据返回结果进行判断如何进行业务操作处理:
  • 失败:放弃业务操作处理,结束(必要时向上层返回失败结果);
  • 成功:执行业务操作处理;
  1. 业务操作完成后,把业务操作结果(成功/失败)发送给消息中间件;
  2. 消息中间件收到业务操作结果后,根据业务结果进行处理;
  • 失败:删除消息存储中的消息,结束;
  • 成功:更新消息存储中的消息状态为“待发送(可发送)”,紧接着执行消息投递;
  1. 前面的正向流程都成功后,向被动方应用投递消息;

七、待解决问题

消息发送一致性方案的正向流程是可行的,但异常流程怎么处理呢? 消息发送到消息中间件中能得到保障了,但消息的准确消费(投递)又如何保障呢? 有没有支持这种发送一致性流程的现成消息中间件?

八、待续

分布式事务五

  • 13
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
------------ #### 介绍 **RMQ**(reliable-message-queue)是**基于可靠消息最终一致性**的分布式事务解决方案。 如果感觉有帮助,帮忙点个star! # [中文文档](https://www.showdoc.cc/rmq "中文文档") - 中文文档地址:[https://www.showdoc.cc/rmq](https://www.showdoc.cc/rmq "https://www.showdoc.cc/rmq") ##### RMQ对接示例: - [https://gitee.com/NuLiing/reliable-message-samples](https://gitee.com/NuLiing/reliable-message-samples "https://gitee.com/NuLiing/reliable-message-samples") - [-samples](-samples "-samples") ## 框架定位 - RMQ本身不生产消息队列,只是消息的搬运工。 - RMQ框架提供消息预发送、消息发送、消息确认、消息恢复、消息管理等功能,结合成熟的消息中间件,解决分布式事务,达到数据最终一致性。 ------------ #### Maven模块描述 | 模块名称 | 描述 | | ---------------- | ------------------------------------------------------------ | | rmq-api | 提供业务系统调用的RMQ服务接口 | | rmq-service-api | 基础消息服务接口、系统工具类、实体类封装 | | rmq-service | RMQ服务接口实现、基础消息服务接口实现、消息管理子系统服务接口实现 | | rmq-schedule-api | 消息确认子系统、消息恢复子系统服务接口 | | rmq-schedule | 消息确认子系统,与上游业务系统确认消息是否发送<br>消息恢复子系统,重新发送消息给下游业务 | | rmq-cms-api | 消息管理子系统服务接口、实体类封装 | | rmq-cms | 消息管理子系统,提供消息管理后台 | | rmq-dal | 数据库访问层: sql语句 | ------------ ## 业务系统对接RMQ 详细对接说明请查看《[快速入门](https://www.showdoc.cc/rmq?page_id=1815635527586509 "快速入门")》和《[对接示例说明](https://www.showdoc.cc/rmq?page_id=1820953552972418 "对接示例说明")》 #### maven依赖 在业务系统的pom文件中引入rmq-api最新版本依赖: ``` # 中央仓库: https://search.maven.org/search?q=rmq-api <dependency> <groupId>com.gitee.nuliing</groupId> <artifactId>rmq-api</artifactId> <version>${最新稳定版本}</version> </dependency> ``` #### 在业务代码中引入RMQ的Dubbo服务 ``` import org.apache.dubbo.config.annotation.Reference; import com.cn.rmq.api.service.IRmqService; @Reference private IRmqService rmqService; ``` #### 编写消息发送方业务方法 ``` public void doBusiness() { // 自定义消息队列名称 String queue = "test.queue"; /

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值