来源:http://t.cn/E4ejkSN

在之前的文章中,我们介绍了基于TCC模式的分布式事务解决方案

我说分布式事务之TCC 。

TCC适用于公司内部对一致性、实时性要求较高的业务场景,而本文我们讲解的“最大努力通知型事务”是为解决跨网络、跨服务之间的柔性事务的另一种解决方案。

首先看一下最大努力通知型的流程图,如下图

我们根据图中的内容,逐步分析一下该方案的业务流程。

1. 原理

首先阐述一下该方案的原理,根据图中所示,

业务活动的主动方(通知发起方),在完成本地业务活动处理后,会向业务活动被动方发送消息【箭头1】, 将业务执行结果通知给业务被动方【箭头4】。这个过程允许消息丢失,如果发生丢失的情况,服务主动方能够通过重试尽力实现双方的数据一致性。此处的的重试就体现出了–最大努力 的特点。

然后是业务的被动方。业务被动方会暴露一个业务结果接收接口(或者叫回调接口也可以)给业务主动方【箭头4】,对收到的通知消息进行必要的校验,校验通过后执行本地业务,从而使业务达到闭环。

同时,由于主动方对被动方的通知次数是有限的,即我们不可能无限制的通知,因此业务活动主动方需要提供一个业务查询补偿接口供被动方使用【箭头5】,被动方会根据定时策略,向业务活动的主动方发起查询操作,从而对丢失的业务消息达到补偿的目的。

整个过程中,业务被动方暴露给主动方的通知接收接口 以及 业务主动方提供给被动方进行查询操作的接口均需要实现幂等,这样才能保证数据完整性不会被破坏,从而实现最终一致性。

2. 详解

接下来,我们详细展开对该方案的讲解。

在这个方案中,我们要求被动方的业务处理结果不能影响业务主动方的处理,双方的职责是清晰的,例如:我们接入支付宝的支付功能,我方的身份即业务被动方,而支付宝方则为业务主动方。

我方接收到用户的支付请求,等待用户输入支付密码,用户支付确认后,我方向支付宝发起支付请求,同步返回给用户预支付结果。此时,用户看到支付处理中。

当支付宝侧执行转账完成之后(图中的箭头1),结果可以是成功/失败,总之主动方一定是在本地业务有确定的执行结果后,才会发起通知。

支付宝侧会通过某种机制(猜想是图中的消息队列机制)将通知请求扔到通知消息服务中,通知发送核心业务消费通知消息,并记录持久化消息到数据库中,发送通知消息给我方。

我方支付回调接口收到支付完成通知后,会对参数进行签名校验,待签名通过后,取出业务参数,对这笔支付订单返回的结果进行后续操作(修改状态为下单完成并发货或者修改为支付失败,操作回滚/退款)。

这个过程理想状态下是很快的,由于支付宝侧强大的处理能力,我们几乎感觉不到处理中状态,但整个过程确实是异步的过程。

【这里给我们的启示之一便是,对于跨系统的交互,如果能够将同步的业务操作拆分为异步过程,能够大幅度提高业务的灵活度及吞吐量。】

这里存在一种普遍的情况,我们的系统处理能力是有限的,在收到通知后未能及时的处理完成,这时,双方会约定,如果收到通知且处理完成,业务被动方需要返回确定某个状态码,如:“success”,否则认为此次通知失败。

这样,只要我们处理完成就返回“success”,主动方就不会继续通知。否则,主动方会按照一定策略,比如“时间衰减策略”,对通知失败的请求从持久层中取出,比如:24小时内,按照间隔1min、5min、10min、30min、1h、2h、5h、10h的方式,逐步拉大通知间隔,直到达到通知要求的时间窗口上限。这时,就需要被动法主动发起查询。一般这种情况很少,而这么做的目的也是为了使最近的请求更快的被通知回去,我们认为,时间越靠后,通知成功的可能性越少,因为大多数的通知请求在第一次通知发起时就返回了成功success。

PS:这里还有一种措施,就是人工干预,重置通知位点。比如:如果达到最大通知次数依然没有通知成功,那么数据仍旧保存在通知库里面,运营人员在接收到商户的重复通知需求的时候,通过人工的操作,重新重置通知次数,这样消息就可以重新通知了。

这种情况往往是业务被动方未接入主动查询导致的,不建议频繁采用此方案,正常的流程时在开发阶段就强烈要求被动方将通知接口及查询接口均开发完成。

说多了都是泪,笔者曾经在工作中从事过一段时间商户接入工作,就遇到过这种类型的商户,经常要求我们为他们重新发起通知,对工作效率的影响真是肉眼可见的。

我们说回正题,在异常情况下,如果业务主动方在一定时间阈值内未能及时的发起通知,而作为业务被动方的我们又想及时获取到业务结果,这时就需要业务被动方主动发起查询,调用主动方暴露的查询接口获取业务结果,这里一般采用定时作业轮询,从而在业务上达到闭环, 最大可能的保证了数据的一致性。

3. 方案评价

  1. 方案成本:该方案成本较低,主要花费在业务查询与校对系统建设成本。校对系统是单独的,例如离线的文件对账方式,通过双方定时导出日订单,做线下的互相对账,从而实现平账操作。

  2. 适用范围:本方案适用于对时间敏感性较低的业务,比如充值、转账业务,在内部系统间就不适合该方式。多适用于跨系统、跨业务、跨网络的服务间数据一致性保证场景。

  3. 用到的服务模式为: 可查询操作,幂等操作等。

  4. 方案特点:

业务活动的主动方在完成业务处理后,向被动方发送通知消息(允许消息丢失);

主动方可以设置时间阶梯型通知规则,在通知失败后按规则重复发起通知,直到通知N次后不再通知

主动方提供校对查询接口给被动方,被动方按需校对查询,用于恢复丢失的业务消息

应用案例

  1. 支付渠道接入通知,银行转账通知、商户通知等

  2. 对账通知(实时/定时)

4. 实现方式

从本文开始的图中可以看出,通常采用两种方式实现

  • 定时任务,使用定时作业轮询发起直接通知,通知数据要做持久化操作。几乎无外部依赖。

  • 定时消息队列,基于定时消息发起通知,同样需要对通知请求数据做持久化操作,对消息队列有高可用需求。


5. 如何优化

  1. 在业务系统外增加业务管理系统,对通知失败数据进行管理,实现手动触发重复通知操作。

  2. 将通知服务通用化,框架化,剥离通知逻辑与业务逻辑, 对通知队列进行区分, 不同队列使用不同通知规则,并且支持通知策略的可配置性操作等。

  3. 保证通知服务的可用性,必要时建立独立的数据库,这里要注意对通知数据的持久化策略,以及通知失败后重新发起通知的策略的优化,比如时间衰减策略的设置等。这对通知的成功率和实效性有很大影响。

  4. 要求主动方提供的业务查询接口及被动方暴露的通知处理业务接口均要实现幂等性。

  5. 最后要注意,内存调优与流量控制,这里主要针对业务主动方,如果通知消息的生产方的速率与通知发送侧的消费方的消费速率不匹配,会导致大量消息驻留在消费端内存中,导致消息服务响应慢,甚至挂掉,从而影响到服务被动方进行业务后续处理,导致更大的商业纠纷等。(这里再插一句,考虑到极端情况,如果真的出现down机,在服务重启后,要能恢复现场,因此对通知消息的持久化操作就是必不可少的。当服务重启后,通知服务能够定位到上次的消费位点,继续通知操作)


6. 小结

本文对分布式事务解决方案的– 最大努力通知型 柔性解决方案进行了较为详细的讲解,结合实例及笔者的工作经历,对方案的各个细节展开讲解,希望能够对读者有所帮助。

后续笔者会着手开发一款分布式事务的轮子,入手点将采用本文提到的模式,并最终达到基本可用。算是立了一个flag吧,完成之后会第一时间发文出来。(又一个有生之年系列)

到目前为止,《我说分布式事务》 系列就过半了,之后我会对可靠消息一致性方案进行讲解,我们不见不散。

·END·

 近期热文:

  • 没错,老板让我写个 BUG!

  • 我说分布式事务之TCC

  • 彻底搞懂 Git-Rebase

  • 让你的系统“坚挺不倒”的最后一个大招——「降级」

  • 不可错过的CMS学习笔记

  • 致敬| 她永远地离开了,但我们依然每天收益于您的伟大发明!

  • 在生产中使用Java 11:需要了解的重要事项

  • 如何在到处是“雷”的系统中「明哲保身」?这是第一招

  • 可能是最全面的G1学习笔记

  • Spring Cloud Stream消费失败后的处理策略(四):重新入队(RabbitMQ)

看完,赶紧点个“好看”鸭

点鸭点鸭

↓↓↓↓

我说分布式事务之最大努力通知型事务相关推荐

  1. 分布式事务模型--最大努力通知型分布式事务

    本文来说下分布式事务模型之最大努力通知型分布式事务 文章目录 概述 最大努力通知型分布式事务 举个例子 特点剖析 本文小结 概述 事务是一组不可分组的操作集合,这些操作要么都成功执行,要么都取消执行. ...

  2. 《深入理解分布式事务》第十章 最大努力通知型分布式事务原理

    <深入理解分布式事务>第十章 最大努力通知型分布式事务原理 文章目录 <深入理解分布式事务>第十章 最大努力通知型分布式事务原理 一.适用场景 二.方案特点 三.基本原理 四. ...

  3. 【死磕Sharding-jdbc】—–最大努力型事务

    2019独角兽企业重金招聘Python工程师标准>>> BASE Transaction Best efforts delivery transaction (已经实现). Try ...

  4. shardingjdbc (九)-最大努力型事务

    一 序: Sharding-JDBC由于性能方面的考量,决定不支持强一致性分布式事务.目前支持的: Best efforts delivery transaction (已经实现). Try conf ...

  5. 七种常见分布式事务详解(2PC、3PC、TCC、Saga、本地事务表、MQ事务消息、最大努力通知)

    分布式事务:在分布式系统中一次操作需要由多个服务协同完成,这种由不同的服务之间通过网络协同完成的事务称为分布式事务 一.2PC: 2PC,两阶段提交,将事务的提交过程分为资源准备和资源提交两个阶段,并 ...

  6. 分布式事务(三)、柔性事务之 TCC、Saga、本地消息表、事务消息、最大努力通知

    目录 [前言] TCC Saga [通知型事务] 本地消息表 MQ事务消息 最大努力通知 总结 分布式事务: 分布式事务(一).CAP,BASE理论 分布式事务(二).刚性事务之 2PC.3PC [前 ...

  7. java分布式事务——最终一致性,最大努力通知总结!

    目录 源码地址:https://github.com/kaixuanzhang123/dtx.git 4.分布式事务解决方案之可靠消息最终一致性 4.1.什么是可靠消息最终一致性事务 4.2.解决方案 ...

  8. 分布式事务解决方案之最大努力通知 上篇

    最大努力通知正向流程 材料摘自龙果学院:http://www.roncoo.com/ 用到的服务模式 可查询操作 方案特点 业务活动的主动方在完成业务处理后,向业务活动的被动方发送通知消息(允许消息丢 ...

  9. mysql 事务补偿_TCC补偿性策略_彻底学习数据库事务 seata分布式事务 共享 排它锁 死锁 索引 Spring事务 隔离级别等_MySQL视频-51CTO学院...

    课程总计41课时,从什么是事务讲起,直到分布式事务解决方案,很的0基础基础与提升系列课程.对于难以理解的知识点,全部用画图+实战的方式讲解. 彻底明白事务的四个特性:原子性.一致性.隔离性.持久性,用 ...

最新文章

  1. UGUI_判断鼠标或者手指是否点击在UI上
  2. 58到家MySQL军规升级版(转:2018-03-30 58到家DBA 架构师之路)
  3. SQLite 表达式(http://www.w3cschool.cc/sqlite/sqlite-expressions.html)
  4. JoinGroup的过程
  5. IOS基础之毛毛虫案例-重力
  6. C# 10 新特性 —— Lambda 优化
  7. .NET Core2使用Azure云上的Iot-Hub服务
  8. Spring入门(三)之IoC
  9. python classmethod 与 staticmethod
  10. 北京互联网人寒冬求职记
  11. 资源编译器 rc .exe 的参数
  12. Unity显示帧率代码
  13. matlab函数sinh,matlab sinh 使用方法
  14. Spring Cloud 常用注解
  15. 高中信息技术:网络基础知识(IP地址、网页设计)、多媒体技术(图像PS、音频、视频、动画)
  16. 世界坐标系、相机坐标系、图像平面坐标系
  17. 希捷硬盘无法安全弹出如何解决?
  18. leader说用下httpclient的重试,但我没用,因为我有更好的方案。
  19. QWebEngineView播放视频最大化
  20. 年薪翻倍的100篇面经:如何转型AI拿到阿里等大厂的40万offer

热门文章

  1. linux cmake 交叉编译配置 简介
  2. python3 socketserver模块 网络服务编程框架
  3. mysql 创建用户与授权
  4. 数字货币 BCH的混币神器CashShuffle
  5. linux kernel devel和kernel source的区别
  6. DLL延迟加载工程分析
  7. Service与AIDL详解
  8. Android开发--Notification和PendingIntent
  9. admob html5,AdMob发布Windows手机SDK并支持HTML5
  10. xampp mysql mac_如何在mac上用终端打开XAMPP自带的MySQL