消息传递一致性分析

分布式系统中消息队列常用于解决服务解耦,异步通信等问题,从而实现服务高性能,以及业务最终一致性。

这里业务最终一致性指消息上游业务和消息下游业务,在一段时间延迟后,业务逻辑的正确性。

为保证最终一致性,就需要上下游对某个业务操作执行一致的逻辑,同时成功或同时失败。

而业务操作的事件我们是通过消息来传递的,那就要求业务操作与消息传递一致性:

  • 上游业务操作和消息发送事务的一致性

  • 下游业务操作和消息消费事务的一致性

也就是:

  • 消息发送一致性:上游主分支事务与消息发送事务的一致

  • 消息消费一致性:下游支分支事务与消息消费事务的一致

消息发送一致性

常规的消息发送无法保证消息发送的一致性。常见的解决方案有:

  1. 分布式事务协议XA

  1. 本地事务表

  1. 独立消息服务

  1. 消息队列事务消息

  1. CDC消息同步

  1. 消息确认

  1. 实时计算

  1. 分布式事务协议XA

消息队列的引入是为解决服务耦合与性能问题,XA协议因为其性能较差,所以一般不会采用该方案。

  1. 本地事务表

本地事务表核心思路是新增本地消息表,业务操作与消息写入利用本地事务一致性提交。

本地事务表交互流程如下:

  1. 应用业务操作和消息写入使用本地事务一致性提交

  1. 应用定时程序,扫描消息表,发送消息到消息队列,并更新消息状态

该方案:

  1. 业务表与消息表耦合,每个业务库都需要增加消息表,且数据量较大,操作频繁。

  1. 业务表与消息表共用数据库,影响业务性能,降低可用性与扩展性。

  1. 事务消息

事务消息核心思路是消息队列提供半事务消息,通过两阶段确认消息操作。第一阶段保留消息信息,第二阶段确认消息操作,如第二阶段出现异常,通过消息回查确认消息操作。

事务消息交互流程如下:

  1. 应用发送半事务消息

  1. 应用进行业务操作

  1. 应用发送事务确认消息

  1. 消息队列根据事务确认消息,决定是否投递消息

  1. X时间前,未确认的半事务消息,消息队列进行消息回查,根据回查结果,确定投递操作。

该方案:

  1. 消息队列耦合应用:消息队列回查消息,应用需提供回查功能,以确保消息发送的一致性

  1. 应用需通过二阶段确认消息操作,第一阶段失败,则业务失败,所以需要尽可能保证消息队列可用性

  1. 独立消息服务

独立消息服务与事务消息机制相似,都是通过二阶段来确认消息操作。

独立消息服务作为消息队列的代理,提供事务消息功能,同时以RPC服务的形式提供给应用使用。

独立消息服务交互流程如下:

  1. 应用发送原消息

  1. 应用进行业务操作

  1. 应用发送确认消息

  1. 消息服务根据确认消息,决定是否将原消息是否发送到消息队列

  1. X时间前未确认消息消息服务向应用回查消息,确认操作(应用与消息服务相互调用)

为解耦应用与消息服务,消息服务可将未确认消息投递到 异常消息队列,应用消费消息,查询业务操作结果,确定发送无需确认的消息。这样独立消息服务无需调用应用,解耦相互调用。

独立消息服务相比事务消息还具有以下特点:

  1. 消息服务作为消息队列的代理,提供事务消息功能,扩展方便灵活。

  1. 消息服务区别于业务服务与消息队列,可根据场景选择合适的高性能的存储

  1. CDC消息同步

利用数据CDC技术,业务数据变更后,将相应数据发送到消息队列,下游应用进行消费。同样该方案CDC技术本身需确保数据变更与消息发送的一致性,不能出现丢失消息的情况。

CDC消息同步方案交互流程如下:

  1. 应用进行业务操作

  1. 数据库数据变更

  1. 数据库CDC发送变更时间到消息队列

  1. 消费确认

消费确认方案核心思路为:应用自身消费消息,确认消息是否发送成功。

消费确认方案交互流程如下:

  1. 应用进行业务操作

  1. 应用发送消息

  1. 应用订阅消息,消费消息,并将标识入库

  1. 应用定时程序,扫描业务表与确认表

  1. 获取X时间前,没有确认的业务数据,构建消息重新发送消息

  1. 超出某个时间,还未确认的业务数据,记录起来,并报警通知人工处理

消费消息入库,可选择不同于业务库的不同类型的存储库。

该方案:

  1. 应用自身控制整个流程

  1. 应用只发送一次消息

  1. 实时计算

实时计算核心思路为:应用发送原消息与确认消息,实时计算匹配消息成功,将原消息发送到最终消息队列中。

实时计算方案交互方案如下:

  1. 应用发送原消息

  1. 应用进行业务操作

  1. 应用发送确认消息

  1. 实时计算匹配原消息与确认消息

  1. 匹配消息,根据确认消息决定是否发送原消息到最终消息队列

  1. 未匹配消息,X时间后进入确认异常消息队列

  1. 应用订阅异常消息队列,查询业务操作结果,确定是否发送原消息到最终消息队列

  1. 异常消息队列多次投递未成功,进入死信队列,报警通知人工处理

该方案:

  1. 引入实时计算。尽可能使用实时计算框架保证高可用与多个消息操作事务一致性。

消息消费一致性

消息消费一致性较为简单,主要基于以下特性来解决:

  1. 消息消费ACK:下游业务操作成功,需ACK消息,否则消息队列会重复投递消息

  1. 业务操作幂等性:上面消息为保证消费成功会重复投递,所以服务需保证业务操作幂等性,不会因消息重复消费而出错。

总结

  1. 消息队列引入目的是解耦应用,提高性能,降低响应,同时需要保证业务最终一致性。

  1. 消息队列保证上下游应用的业务最终一致性,要求上下游应用保障业务操作与消息传递事务一致性即:

  1. 消息发送一致性

  1. 消息消费一致性

  1. 消息发送一致性通常通过多阶段来实现

  1. 消息消费一致性通过 消息消费ACK+ 业务操作幂等性 保证

  1. 几种消息发送一致性方案简单说明:

  1. 分布式事务协议XA,性能较差

  1. 本地事务表,数据库耦合,性能差且受影响

  1. 事务消息,需消息队列支持,且消息回查耦合业务应用

  1. 独立消息服务,消息队列代理,通过异常消息队列避免与应用循环调用

  1. CDC消息同步,依赖数据库CDC技术

  1. 消费确认方案,应用控制整个流程,消息只发送一次

  1. 实时计算方案,引入实时计算

  1. 基于以上介绍,消息发送一致性方案推荐顺序为CDC消息同步、事务消息,消息确认。

参考

MQ消息最终一致性解决方案 - 掘金

分布式事务(六)之可靠消息最终一致性 - 掘金

RocketMQ事务消息的应用场景、功能原理及使用说明_消息队列 MQ-阿里云帮助中心

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

salahi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值