再探蚂蚁中间件:MsgBroker

所有中间件都是为了解决特定领域的某个问题。
MsgBroker解决:分布式系统的消息传递的问题。

首先先了解消息中间件的一些背景知识


1.消息中间件

1.1消息中间件是什么

  • 消息中间件用于分布式系统的消息传递
  • 利用高效可靠的消息传递机制进行与平台无关的数据交流
  • 基于数据通信来进行分布式系统的集成
  • 通过提供消息传递和消息排队模型

1.2为什么要有消息中间件

原本的RPC接口调用有什么问题

  • 客户端服务进程和服务端服务进程的生命周期紧密耦合,紧密耦合带来三个问题
  • 客户端进程和服务端进程必须都正常运行,如果由于服务方的对象错误或者网络错误等引起的请求不可达,客户端的请求就会异常。
  • 后续客户端有其他业务变更的时候服务端的服务也得做出相应调整。
  • 同步处理导致服务端需要等待客户端处理完后才能处理完,处理时间慢。

消息中间件解决了什么问题

  • 客户端和服务端的对象生命周期的松耦合关系:客户端进程和服务端对象进程不要求都正常运行,如果由于服务对象崩溃或者网络故障导致客户的请求不可达,客户不会接收到异常,消息中间件能保证消息不会丢失。
  • 用异步通信模式:发送消息者可以在发送消息后进行其它的工作,不用等待接收者的回应,而接收者也不必在接到消息后立即对发送者的请求进行处理;

一个例子

一个账单查询Case,基本业务逻辑:

  1. 账单服务:检索数据库,获取指定账户的账单记录。
  2. 风险控制服务:记录用户的检索行为,为风险控制提供数据积累。
  3. 短信通知服务:发送短信到用户手机,通知用户其账单被查询事件。

方案1,同步RPC调用

image

方案2,异步消息中间件

image

方案2对比方案1的优点:

  • 账单服务处理这个case时间减少了许多,提高了吞吐量
  • 账单服务,风险控制服务和短信通知服务完全解耦,后续有其他业务变更时,账单服务不需要变更
  • 风险控制服务和短信通知服务不可用时,不会导致账单服务不可用

1.3消息中间件应用场景

  • 系统集成:系统集成除了通过接口还可以通过消息。不同点:接口通过模块间直接调用;使用消息中间件的系统通过消息模块通信,通过消息来分解系统。
  • 业务解耦:如果模块之间不存在直接调用,那么修改或新增模块对其他模块影响最小。增加消息中间件后,业务模块仅需关注自己的业务逻辑和如何将消息发送给消息服务器,消息由中间件存储和分发。
  • 异步处理:多个应用对消息中间件的同一消息处理,应用间并发处理消息,比起串行处理,减少处理时间。
  • 改善系统性能(削峰填谷):比如上游系统的吞吐能力高于下游系统,在流量洪峰时可能会冲垮下游系统,消息中间件可以在流量高峰时堆积消息,而在峰值过去后下游系统慢慢消费消息解决流量洪峰的问题
  • 跨平台:跨平台使用,降低网络协议的复杂性
  • 事务型消息:基于消息的通信是可靠的,消息不会丢失。可以发送事务性消息,而且大多数消息中间件都提供将消息持久化到磁盘的功能。

1.4消息中间件主要特点

  • 可靠性:基于消息的通信是可靠的,大多数消息中间件都提供将消息持久化到磁盘的功能,可以发送离线消息,消息不会丢失。在分布式事务中担当重要的角色。
  • 异步:基于事件驱动架构,将调用异步化
  • 分布式:消息中间件都是分布式的

1.5两种模式

点对点模式 (point to point)

点对点模式下包括三个角色:

  • 消息队列
  • 发送者 (生产者)
  • 接收者(消费者)


    image

消息发送者生产消息发送到queue中,然后消息接收者从queue中取出并且消费消息。消息被消费以后,queue中不再有存储,所以消息接收者不可能消费到已经被消费的消息。

点对点模式特点:

  • 每个消息只有一个接收者(Consumer)(即一旦被消费,消息就不再在消息队列中);
  • 发送者和接收者间没有依赖性,发送者发送消息之后,不管有没有接收者在运行,都不会影响到发送者下次发送消息;
  • 接收者在成功接收消息之后需向队列应答成功,以便消息队列删除当前接收的消息;

发布/订阅模式(publish/subcribe)

发布/订阅模式下包括三个角色:

  • 角色主题(Topic)
  • 发布者(Publisher)
  • 订阅者(Subscriber)
image

发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。

发布/订阅模式特点:

  • 每个消息可以有多个订阅者;
  • 发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。
  • 为了消费消息,订阅者需要提前订阅该角色主题,并保持在线运行;

1.6消费消息的推拉模式

  • 推模式push:由消息中间件主动发消息给消费者
  • 拉模式pull:消费者主动从消息中间件拉取消息
  • 比较:采用push模式,可以尽可能快的把消息发给消费者,但是如果消费者处理一条消息能力较弱(处理时间长),消息中间件会不断的发消息给消费者,到时消费者的缓存区溢出;采用pull模式,可能会增加消息的延迟。

1.7引入消息中间件需要注意点

  • 复杂性:消息中间件都是分布式的,引入分布式会大大增加系统复杂度,在不同主机、不同进程之间的调用和调试,会带来更多的不稳定性。分布式系统还会增加对外部系统的依赖。即使自己的系统没有问题,也可能会因为依赖系统出问题而导致系统不稳定。
  • 异步调用:带来的业务交互的改变,有一定的操作延迟。
  • 同步调用:尽管消息中间件也可用于同步调用,但这并不是它的长项,同步调用可以考虑使用HTTP、NIO等其他方式。
    然后再看蚂蚁的消息中间件msgbroker是怎么做的,重点讲述MsgBroker的事务型消息

2.MsgBroker

2.1MsgBroker原理架构图

image

2.2MsgBroker组成

  • 消息发布者Publisher:发送消息的应用系统,发送消息到可靠消息组件 (MsgBroker)。
  • 可靠消息组件MsgBroker:即MsgBroker,负责接收发布者发送的消息,根据消息类型和订阅关系将消息分发投递到一个或多个消息订阅者。
  • 消息订阅者Subscriber:指订阅消息的应用系统,收到的消息来自可靠消息组件 (MsgBroker)。
  • 消息类型Message Type:一种消息类型由 TOPIC 和 EVENTCODE 唯一标识。
  • 订阅关系Binding:用来描述一种消息类型被订阅者订阅。

2.3Msgbroker特性

  • 可靠性:MsgBroker确保消息可以投递到订阅者,发送者和订阅者都不必担心消息丢失
  • 事务一致性:保证消息和本地数据库事务的一致性
  • 不保证消息不重复:所以订阅者要做好幂等
  • 不保证消息投递顺序:如果订阅者有需求需要自己实现

2.4普通消息

普通消息:较简单的发送和投递两个过程


image

2.5事务型消息

什么是事务型消息

一种特殊类型的消息:消息中间件收到消息发布者发布的消息后不会立刻投递给消费者,而是根据发布者应用的数据库事务状态来决定是否投递,如果数据库事务是提交,就投递;是回滚就不投递。

为什么要设计事务型消息

为了保证在分布式系统中数据库变更之间以及数据库变更和业务处理保持事务一致性。

事务型消息如何保证数据一致性

事务型消息通过“二阶段”来保证一致性

  • 第一个阶段:当发送端像发送普通消息一样,将消息发送给Broker,Broker会将该条记录保存在数据库中,并将其事务状态设置为未知状态。 入库操作完成后,Broker会向发送端返回一个消息确认的信息,一阶段结束。
  • 第二个阶段:发送端的代码包在事务模板中,当这个事务完结的时候,发送端会将本地事务的执行结果(提交/回滚)发送给Broker,Broker对结果做出判断。提交则发送,回滚则不发送

思考

  1. 为什么发送消息要在事务操作之前?
  2. 如果Msgbroker一直收不到事务的执行结果状态(提交/回滚)时要怎么办?
  1. 第一个问题,如果顺序反过来,先执行事务,事务执行完成提交后再发送消息,那么消息发送失败就会导致本地事务回滚,这个肯定是不合理的,因为事务回滚比重发消息代价高很多
  2. 第二个问题,如果MsgBroker一直没收到事务的执行结果,这个在分布式系统里属于异常情况,也是有可能发生的,比如 说网络异常等,而Msgbroker作为一个严谨的消息中间件也考虑到了这种异常情况,设计了“回查阶段”,这个阶段只会在事务“提交/回滚消息”失败时才会被触发。

总结

  • 消息中间件MsgBroker事务型消息通过“二阶段”消息实现
  • 事务型消息是否投递与本地事务状态保持一致
  • 事务型消息状态回查是为了保证事务型消息的严谨性

事务型消息(事务成功时消息才提交):


image

事务型消息(事务回滚时不发送消息):


image

4.几个消息队列比较

电商、金融对事务型消息要求较高,因此MsgBroker重点在于支持事务型消息

MsgBroker RocketMQ ActiveMQ RabbitMQ KafKa
所属公司社区 蚂蚁 阿里 Apache Mozilla Apache
开发语言 Java Java Java Relang Scale&Java
消息消费模式(pull/push) push 多协议,均支持 多协议,均支持 多协议,均支持 pull
数据可靠性 可靠 可靠,同步刷盘,同/异步复制 可靠,master/slave 保证数据不丢,slave备份 可靠,replica机制,容错容灾
持久化能力 DB 磁盘文件 内存/文件/DB DB / 文件 磁盘文件
是否有序 无序 有序 可以支持有序 一个Client才有序 多Client有序
事务型消息 支持 支持 支持 不支持 不支持
负载均衡 支持 支持 支持 支持 支持
关键场景 事务,高可靠 高吞吐,高可靠 高扩展 高并发,高可靠 高吞吐,分布式

5.知识点回顾

从本地事务到分布式事务到消息队列

5.1事务

事务:一系列指令的集合

满足:ACID原则

  • Automicity(原子性):操作这些指令,要么全部成功,要么全部失败
  • Consistency(一致性):事务执行使得数据库从一个状态到另一个状态,但是对于整个数据的完整性保持一致
  • Isolation(隔离性):在一个事务执行过程中,任何数据变更都只存在于这一个事务中,不会被外界感知,只有事务执行完成后,其他事务才能感知到这个事务引起的数据变更。
  • Durability(持久性):事务正确完成后,它带来的数据变更时永久的。

5.2本地事务

本地事务是在单个数据源上进行数据访问和更新,资源由资源管理器本地管理


image

本地事务特点:

  • 一次事务只连接一个支持事务的数据库
  • 事务的执行保证ACID原则
  • 会用到数据库锁

5.3分布式事务

跨越多个数据源进行数据访问和更新。
随着业务变得复杂,一个单机应用的一个数据库会被拆成多库多表,一个应用也会被拆成多个应用,整个系统处于分布式的状态,这个时候就需要保证分布式架构下的数据一致性。关于分布式事务在之后学习XTS中间件的时候再深入了解。

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

推荐阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 31,912评论 2 89
  • 概念:微服务就是一些可独立运行、可协同工作的小的服务。微服务是现在特别流行的服务,微服务的字面意思是大家都很好理解...
    程序员技术圈阅读 3,339评论 2 47
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 实习,发快递。觉得这事很傻,而自己还出错,好像更傻。在此类事情上消磨生命我觉得疲惫,我爸妈说是必须的锻炼,或许他们...
    AnnaSun0705阅读 267评论 2 2