RocketMQ进击(零)RocketMQ这个大水池子

x33g5p2x  于2021-12-19 转载在 其他  
字(7.0k)|赞(0)|评价(0)|浏览(297)

楔子:项目中,开发很容易忽视的一点是,只想到或者只想做自己应该做的事。这是非常有碍自己进步和自我放弃的一个心态或决策。实际上,只要你置身于万物中,每个层阶都是这样。所以,相比拎包入住的租赁市场的成熟与便利,开包即用的项目开发,是团队协作的精华,而我们要做的就是制作那些精华。

1. 枯燥无味

不管是单击游戏,还是吃鸡游戏,抛开主观情感,其路子本质基本上都是打怪升级成就无量至尊。所以,无论是主线还是支线任务,是副本还是打野,攒经验升级前,我们先要做的基本上都是 是什么、为什么、做什么、怎么做(用)、怎么做(用)能快速高效等等,只是游戏让这些问题都变得潜移默化顺乎所以。

那 MQ 是什么?我为什么要 Get 她?她能做什么?我要怎么做/用?什么时候用?怎么做/用可以更快速高效?

理论的产生从是来枯燥无味,不妨让理解理论的过程变得有趣一点。

2. 大水池子

我们可以想像有一个大水池子,里面的水时而被使用殆尽,时而又被注入新水,常此以往,这池水物泽苍生大地经久不息。而注入新水为生产者(Producer)、使用水源为消费者(Consumer),这个大水池子就是服务器(Name Server、Broker),大水池2、大水池3 ... 的互通就是服务器集群,消费工具就是水管管道(订阅 Topic)。 

  • 居民区B对水池2的消费使用突增,水池1、水池3的水源会互通调节注入,以防水池2被使用干涸,这可以理解为服务器的削峰填谷
  • 居民区B的B001户人家使用大水池的水,并不会影响居民区A的A001户人家;且B001户人家要开始洗衣做饭拖地啦。这个指令一下,洗衣机要用水开始洗衣,厨房要放水洗菜洗碗,阳台要放水洗拖把,但是并不会相互产生制约,因为没有只能洗衣放水而做饭停水,也没有只能洗菜有水而洗拖把没水的顾虑。这就是异步解耦
  • 顺序消息也好理解,比如B001户的小朋友哭着要吃牛奶了,这个指令的前置条件是奶粉+温开水,开水不行,小朋友马上就要喝的,冷水也不行,所以这个收到泡牛奶的消息后,指令就可以拆解为 凉白开 + 开水 + 奶粉 + 轻摇溶解 + 试温 一系列操作后才能给小朋友喝。不然,小朋友不会喝,还哭得更厉害。抑或者洗澡,我们肯定是要在抹完沐浴露后再用水冲洗身子,再用干浴巾擦,最后穿上衣服,而不是抹完沐浴露后不冲也不擦直接穿衣服。这就是完成一条指令信息遵循的先后动作,颠倒不得。
  • 分布式事务消息可以想像成B001户做中饭,这个信息指令可以分工拆解快速的完成:小朋友他爸放水淘米煮饭,小朋友他妈放水洗菜,小朋友奶奶炒菜,小朋友爷爷带娃,这样的流程下来,一家人就可以很快吃到一桌好饭好菜了。相比奶奶一个人带娃又淘米洗菜炒菜要方便快捷得不要太多。

这就是 RocketMQ 的特性和应用场景。

3. 生而不凡

3.1. 那 MQ 是什么?

记忆中第一次玩游戏时,对 RPG 这个名词陌生又熟悉,但我知道自己在玩一款 角色扮演游戏(Role-playing game,简称 RPG)。了解一个事物一般是从 TA 的名字或名称开始的,也有从印象从感觉开始的,但是也有很多例外,像花儿,像TA,像MQ。

消息队列(Message Queue,简称 MQ),是构建分布式互联网应用的基础设施,通过 MQ 实现的松耦合架构设计可以提高系统可用性以及可扩展性,既可为分布式应用系统提供异步解耦和削峰填谷的能力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性。是适用于现代应用的最佳设计方案。具体常见的有如订单消息,支付消息等等。

3.2. 什么是 RocketMQ 呢?

就像你在了解 TRPG (桌上角色扮演游戏,Table-top Role-Playing Game);SRPG (策略角色扮演游戏,Strategy Role-Playing Game) 一样,RocketMQ 也是 MQ 消息队列家庭中的一个系,因为除了 RocketMQ,还有 RabbitMQ、Kafka、MQTT 等等。

Apache RocketMQ 是由阿里巴巴自研,并捐赠给 Apache 基金会,并于开源社区共建的消息中间件,2017年9月25日成为 Apache 的顶级项目。该产品服务于阿里巴巴集团已超过 13 年,经过交易核心链路反复打磨与历年双十一高并发场景的严苛考验,已然是一个真正具备低延迟、高并发、高可用、高可靠,可支撑万亿级数据洪峰的分布式消息中间件。

RocketMQ 经历了三个主要版本迭代:

  1. Metaq(Metamorphosis) 1.x
    由开源社区 killme2008(庄晓丹)维护,最后一次 MetaQ 的更新时间为2013年。
  2. Metaq 2.x
    于2012 年10 月份上线,在淘宝内部被广泛使用。
  3. RocketMQ 3.x
    基于阿里巴巴公司内部开源共建原则,RocketMQ 项目只维护核心功能,且去除了所有其他运行时依赖,核心功能最简化。每个产品的个性化需求都在 RocketMQ 项目之上进行深度定制。

官网:http://rocketmq.apache.org
下载:http://rocketmq.apache.org/dowloading/releases/
GitHub:https://github.com/apache/rocketmq

3.3. 你的名字

做任务,不管是主线还是支线,你都需要在游戏里面找到具体某个“人”(NPC);AT 代表攻击力(Attack);DF 代表防御力(Defense)等等,玩游戏也要玩得得心应手玩得专业的话,就不免需要了解很多的游戏专业术语。

了解 MQ 也是一样,需要了解一些核心概念

  • 消息生产者(Producer)
    负责生产消息,一般由业务系统负责生产消息。一个消息生产者会把业务应用系统里产生的消息发送到 Broker 服务器。RocketMQ 提供多种发送方式:**同步发送、异步发送、顺序发送、单向发送。**同步和异步方式均需要 Broker 返回确认信息,单向发送不需要。详见第三节。
  • 消息消费者(Consumer)
    负责消费消息,一般是后台系统负责异步消费。一个消息消费者会从 Broker 服务器拉取消息、并将其提供给应用程序。从用户应用的角度而言提供了两种消费形式:拉取式消费、推动式消费。详见第三节。
  • 主题(Topic)
    表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是 RocketMQ 进行消息订阅的基本单位。
  • 标签(Tag)
    为消息设置的标志,用于同一主题下区分不同类型的消息。来自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。标签能够有效地保持代码的清晰度和连贯性,并优化 RocketMQ 提供的查询系统。消费者可以根据 Tag 实现对不同子主题的不同消费逻辑,实现更好的扩展性。
  • 消息(Message)
    消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。RocketMQ 中每个消息拥有唯一的 Message ID,且可以携带具有业务标识的 Key。系统提供了通过 Message ID 和 Key 查询消息的功能。
  • 代理服务器(Broker Server)
    消息中转角色,负责存储消息、转发消息。代理服务器在 RocketMQ 系统中负责接收从生产者发送来的消息并存储、同时为消费者的拉取请求作准备。代理服务器也存储消息相关的元数据,包括消费者组、消费进度偏移和主题和队列消息等。
  • 名字服务(Name Server)
    名称服务充当路由消息的提供者。生产者或消费者能够通过名字服务查找各主题相应的 Broker IP 列表。多个 Namesrv 实例组成集群,但相互独立,没有信息交换。
  • 生产者组(Producer Group)
    同一类 Producer 的集合,这类 Producer 发送同一类消息且发送逻辑一致。如果发送的是事物消息且原始生产者在发送之后崩溃,则 Broker 服务器会联系同一生产者组的其他生产者实例以提交或回溯消费。
  • 消费者组(Consumer Group)
    同一类 Consumer 的集合,这类 Consumer 通常消费同一类消息且消费逻辑一致。消费者组使得在消息消费方面,实现负载均衡和容错的目标变得非常容易。要注意的是,消费者组的消费者实例必须订阅完全相同的 Topic。RocketMQ 支持**两种消息模式:集群消费(Clustering)和广播消费(Broadcasting)。**详见第五节。

3.4. 那我为什么要 Get 到她呢?

就像在吃鸡游戏里面你搞到一把98K狙击步枪的狂肆;就像在诛仙游戏里你合成了一套+12装备的狂喜;也像 MQ,她们功能特点和功能特点产生的作用或效果都会让你狂浪。

RocketMQ 的主要特点有:

  1. 灵活可扩展性
    RocketMQ 天然支持集群,其核心四组件(Name Server、Broker、Producer、Consumer)每一个都可以在没有单点故障的情况下进行水平扩展。
  2. 支持顺序消息
    可以保证消息消费者按照消息发送的顺序对消息进行消费。顺序消息分为全局有序局部有序,一般推荐使用局部有序,即生产者通过将某一类消息按顺序发送至同一个队列来实现。
  3. 支持事务消息
    RocketMQ 除了支持普通消息,顺序消息之外还支持事务消息,支持事务消息绝对是亮点,这个特性对于分布式事务来说提供了一种最佳解决方案。
  4. 消息回溯消费
    回溯消费是指消费者已经消费成功的消息,由于业务上需求需要重新消费,RocketMQ 支持按照时间回溯消费,时间维度精确到毫秒,可以向前回溯,也可以向后回溯。
  5. 多种消息过滤方式
    5.1 消息过滤分为在服务端过滤和在消费端过滤
    5.2 服务端过滤时可以按照消息消费者的要求做过滤,优点是减少不必要消息传输,缺点是增加了消息服务器的负担,实现相对复杂
    5.3 消费端过滤则完全由具体应用自定义实现,这种方式更加灵活,缺点是很多无用的消息会传输给消息消费者
  6. 亿级消息堆积能力
    RocketMQ 采用零拷贝原理实现超大的消息的堆积能力,在堆积海量消息后依然保持写入低延迟。

3.5. 她能做什么?

RocketMQ 的应用场景非常多,主要是可以实现分布式系统业务解耦:

  • 削峰填谷:诸如秒杀、抢红包、企业开门红等大型活动时皆会带来较高的流量脉冲,或因没做相应的保护而导致系统超负荷甚至崩溃,或因限制太过导致请求大量失败而影响用户体验,消息队列 MQ 可提供削峰填谷的服务来解决该问题。
  • 异步解耦:交易系统作为淘宝/天猫主站最核心的系统,每笔交易订单数据的产生会引起几百个下游业务系统的关注,包括物流、购物车、积分、流计算分析等等,整体业务系统庞大而且复杂,消息队列 MQ 可实现异步通信和应用解耦,确保主站业务的连续性。
  • 顺序收发:细数日常中需要保证顺序的应用场景非常多,比如证券交易过程时间优先原则,交易系统中的订单创建、支付、退款等流程,航班中的旅客登机消息处理等等。与先进先出(First In First Out,缩写 FIFO)原理类似,消息队列 MQ 提供的顺序消息即保证消息 FIFO。
  • 分布式事务一致性:交易系统、支付红包等场景需要确保数据的最终一致性,大量引入消息队列 MQ 的分布式事务,既可以实现系统之间的解耦,又可以保证最终的数据一致性。
  • 大数据分析:数据在“流动”中产生价值,传统数据分析大多是基于批量计算模型,而无法做到实时的数据分析,利用阿里云消息队列 MQ 与流式计算引擎相结合,可以很方便的实现将业务数据进行实时分析。
  • 分布式缓存同步:天猫双 11 大促,各个分会场琳琅满目的商品需要实时感知价格变化,大量并发访问数据库导致会场页面响应时间长,集中式缓存因为带宽瓶颈限制商品变更的访问流量,通过消息队列 MQ 构建分布式缓存,实时通知商品数据的变化。

4. 江湖奇才

RocketMQ 系统架构部署图:

4.1. 系统架构

1)Producer:消息发布的角色,支持分布式集群方式部署。Producer 通过 MQ 的负载均衡模块选择相应的 Broker 集群队列进行消息投递,投递的过程支持快速失败并且低延迟。

2)Consumer:消息消费的角色,支持分布式集群方式部署。支持以 push 推,pull 拉两种模式对消息进行消费。同时也支持集群方式和广播方式的消费,它提供实时消息订阅机制,可以满足大多数用户的需求。

3)NameServer:NameServer 是一个非常简单的 Topic 路由注册中心,其角色类似 Dubbo 中的 zookeeper,支持 Broker 的动态注册与发现。主要包括两个功能:

  • Broker 管理,NameServer 接受 Broker 集群的注册信息并且保存下来作为路由信息的基本数据。然后提供心跳检测机制,检查 Broker 是否还存活;
  • 路由信息管理,每个 NameServer 将保存关于 Broker 集群的整个路由信息和用于客户端查询的队列信息。然后 Producer 和 Conumser 通过 NameServer 就可以知道整个 Broker 集群的路由信息,从而进行消息的投递和消费。NameServer 通常也是集群的方式部署,各实例间相互不进行信息通讯。Broker 是向每一台 NameServer 注册自己的路由信息,所以每一个 NameServer 实例上面都保存一份完整的路由信息。当某个 NameServer 因某种原因下线了,Broker 仍然可以向其它 NameServer 同步其路由信息,Producer、Consumer 仍然可以动态感知 Broker 的路由的信息。 

4)BrokerServer:Broker 主要负责消息的存储、投递和查询以及服务高可用保证,为了实现这些功能,Broker 包含了以下几个重要子模块:

  1. Remoting Module:整个 Broker 的实体,负责处理来自 clients 端的请求。
  2. Client Manager:负责管理客户端(Producer/Consumer)和维护 Consumer 的 Topic 订阅信息
  3. Store Service:提供方便简单的API接口处理消息存储到物理硬盘和查询功能。
  4. HA Service:高可用服务,提供 Master Broker 和 Slave Broker 之间的数据同步功能。
  5. Index Service:根据特定的 Message key 对投递到 Broker 的消息进行索引服务,以提供消息的快速查询。

4.2. 网络部署


【RocketMQ部署流程一览】

4.2.1 部署架构图解

  • Name Server:是一个几乎无状态节点,可集群部署,在消息队列 MQ 中提供命名服务,更新和发现 Broker 服务。
  • Broker:消息中转角色,负责存储消息,转发消息。分为 Master Broker 和 Slave Broker,一个 Master Broker 可以对应多个 Slave Broker,但是一个 Slave Broker 只能对应一个 Master Broker。Broker 启动后需要完成一次将自己注册至 Name Server 的操作;随后每隔 30s 定期向 Name Server 上报 Topic 路由信息。
  • Producer:与 Name Server 集群中的其中一个节点(随机)建立长链接(Keep-alive),定期从 Name Server 读取 Topic 路由信息,并向提供 Topic 服务的 Master Broker 建立长链接,且定时向 Master Broker 发送心跳。
  • Consumer:与 Name Server 集群中的其中一个节点(随机)建立长连接,定期从 Name Server 拉取 Topic 路由信息,并向提供 Topic 服务的 Master Broker、Slave Broker 建立长连接,且定时向 Master Broker、Slave Broker 发送心跳。Consumer 既可以从 Master Broker 订阅消息,也可以从 Slave Broker 订阅消息,订阅规则由 Broker 配置决定。

4.2.2 集群工作流程

  1. 启动 NameServer,NameServer 起来后监听端口,等待 Broker、Producer、Consumer 连上来,相当于一个路由控制中心。
  2. Broker 启动,跟所有的 NameServer 保持长连接,定时发送心跳包。心跳包中包含当前 Broker 信息(IP+端口等)以及存储所有 Topic 信息。注册成功后,NameServer 集群中就有 Topic 跟 Broker 的映射关系。
  3. 收发消息前,先创建 Topic,创建 Topic 时需要指定该 Topic 要存储在哪些 Broker 上,也可以在发送消息时自动创建 Topic。
  4. Producer 发送消息,启动时先跟 NameServer 集群中的其中一台建立长连接,并从 NameServer 中获取当前发送的 Topic 存在哪些 Broker 上,轮询从队列列表中选择一个队列,然后与队列所在的 Broker 建立长连接从而向 Broker 发消息。
  5. Consumer 跟 Producer 类似,跟其中一台 NameServer 建立长连接,获取当前订阅 Topic 存在哪些 Broker 上,然后直接跟 Broker 建立连接通道,开始消费消息。

**注意:**图文中所提及的消息队列 MQ 的服务端或者服务器包含 Name Server、Broker 等。服务端不等同于 Broker。

参考资料:
RocketMQ 官网:http://rocketmq.apache.org/docs/motivation/
阿里云消息队列 MQ:https://help.aliyun.com/document_detail/29532.html
阿里巴巴中间件团队:http://jm.taobao.org/2017/03/03/RocketMQ-future-idea/

相关文章