RocketMQ的由来
09年,淘宝第一个双十一,那个时候还是IOE的天下(IBM小型机、Oracle数据库、EMC存储设备),仍然扛不住双十一高并发的情况,于是乎阿里巴巴发起了著名的“去IOE”活动, 代之以自己在开源软件基础上开发的系统。
发展历程:
- … , 漫长的积累发展
- 12年,开源自研的第三代分布式消息中间件RocketMQ,
- 16年,RocketMQ进入Apache 孵化
- 如今,RocketMQ已经是Apache的顶级项目。
更多请戳: RocketMQ的前世今生
RocketMQ 版本
- 开源版本
- 商业收费版本
我们这里讨论的都是 开源版本的功能
RocketMQ 基本概念
https://github.com/apache/rocketmq/blob/master/docs/cn/concept.md
RocketMQ中的几个基本概念,还是需要知道的,不然不好理解RMQ的架构图
消息模型
RocketMQ主要由 Producer、Broker、Consumer 三部分组成。
Producer 负责生产消息
Consumer 负责消费消息
Broker 负责存储消息
消息生产者(producer)
负责生产消息,一般由业务系统负责生产消息。
一个消息生产者会把业务应用系统里产生的消息发送到broker服务器。
RocketMQ提供多种发送方式,同步发送、异步发送、顺序发送、单向发送.
同步和异步方式均需要Broker返回确认信息,单向发送不需要。
消息消费者(Consumer)
负责消费消息,一般是后台系统负责异步消费。
一个消息消费者会从Broker服务器拉取消息、并将其提供给应用程序
从用户应用的角度而言提供了两种消费形式:拉取式消费(pull consumer)、推动式消费(push consumer)。
主题(Topic)
表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。
代理服务器(Broker Server)
消息中转角色,负责存储消息、转发消息。
代理服务器在RocketMQ系统中负责接收从生产者发送来的消息并存储、同时为消费者的拉取请求作准备。
代理服务器也存储消息相关的元数据,包括消费者组、消费进度偏移和主题和队列消息等
名称服务(Name Server)
Name Server充当路由消息的提供者。生产者或消费者能够通过Name Server查找各主题相应的Broker IP列表。
多个Namesrv实例组成集群,但相互独立,没有信息交换。
拉取式消费(Pull Consumer)
Consumer消费的一种类型,应用通常主动调用Consumer的拉消息方法从Broker服务器拉消息、主动权由应用控制。一旦获取了批量消息,应用就会启动消费过程。
推动式消费(Push Consumer)
Consumer消费的一种类型,该模式下Broker收到数据后会主动推送给消费端,该消费模式一般实时性较高。
生产者组(Producer Group)
同一类Producer的集合,这类Producer发送同一类消息且发送逻辑一致。
如果发送的事务消息且原始生产者在发送之后崩溃,则Broker服务器会联系同一生产者组的其他生产者实例以提交或回溯消费。
消费者组(Consumer Group)
同一类Consumer的集合,这类Consumer通常消费同一类消息且消费逻辑一致
消费者组使得在消息消费方面,实现负载均衡和容错的目标变得非常容易。要注意的是,消费者组的消费者实例必须订阅完全相同的Topic。
RocketMQ 支持两种消息模式:集群消费(Clustering)和广播消费(Broadcasting)。
集群消费(Clustering)
集群消费模式下,相同Consumer Group的每个Consumer实例平均分摊消息。
广播消费(Broadcasting)
广播消费模式下,相同Consumer Group的每个Consumer实例都接收全量的消息。
普通顺序消息(Normal Ordered Message)
普通顺序消费模式下,消费者通过同一个消费队列收到的消息是有顺序的,不同消息队列收到的消息则可能是无顺序的。
严格顺序消息(Strictly Ordered Message)
严格顺序消息模式下,消费者收到的所有消息均是有顺序的。
消息(Message)
消息系统所传输信息的物理载体,生产和消费数据的最小单位,每条消息必须属于一个主题。
RocketMQ中每个消息拥有唯一的Message ID,且可以携带具有业务标识的Key。
系统提供了通过Message ID和Key查询消息的功能。
标签(Tag)
为消息设置的标志,用于同一主题下区分不同类型的消息. .
來自同一业务单元的消息,可以根据不同业务目的在同一主题下设置不同标签。
标签能够有效地保持代码的清晰度和连贯性,并优化RocketMQ提供的查询系统。
消费者可以根据Tag实现对不同子主题的不同消费逻辑,实现更好的扩展性。
RocketMQ 架构图
Apache RocketMQ借鉴了kafka的架构,对其进行了优,纯Java开发,具有低延迟、高吞吐量、高可用性、适合大规模分布式系统应用的特点。
RocketMQ目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景
它们中的每一个都可以水平扩展,而没有单个故障点 。
四部分组成
- nameserver : 提供轻量级的服务发现和路由。 每个名称服务器记录完整的路由信息,提供相应的读写服务,并支持快速的存储扩展。
- broker : 通过提供轻量级的TOPIC和QUEUE机制来存储消息。
- 生产者
- 使用者
nameserver集群、 生产者集群 、 消费者集群都是无状态的 。
每一个nameserver都存储所有broker集群的信息 。
rocketmq 亮点功能: 支持 分布式事务, 支持SQL92 …
白话RocketMQ的架构图
nameserver , 类似zookeeper注册中心,用来收集broker的信息。 broker都会注册到nameserver .
每个namesrv 都会包含broker集群 主从节点的全部信息。 比如上图 3个namesrv, 4个 broker: 每个namesrv都会包含 broker cluster中的 4个broker的全量信息 。
broker 集群 会向每个namersrv 全量信息。 之所以这样做,因为namesrv 设计的是无状态的,每个namesrv之间是没有关联的。 其中一个namesrv节点挂了,其他的节点是无感知的。 namesrv不支持有状态,选举等功能,所以包含broker cluster的全量信。
我们的producer和consumer 都会配置 全部的namesrv节点的信息,都会配到对应的配置文件中,这也就意味着,当发起心跳拉取信息时,即便有个一个namesrv挂了,还有其他的namesrv节点可用。 只要有个1个namesrv是可用的,就能够获取到broker的信息
.
在最开始, producer和consumer都是没有broker的信息的,都是需要从namesrv上拉取broker集群的信息。 producer 和 consumer 从namesrv拉取信息,也不是实时拉取的,大概30s拉取一次,频率也还好。
相应的, consumer也是无状态的, 比如图上的3个consumer节点, 其中一个挂了,其他两个consumer也是感知不到的,跟这俩consumer也没关系, 同理,producer亦是如此。 每个节点都是单独从namesrv上拉取信息,互相独立。
服务端的话其实即使 namesrv + broker , 然后加上 producer 、consumer 就构成了 RocketMQ的基本组成。
broker一旦启动以后,会有个定时任务主动的向namesrv发送心跳信息(发送broker中的基本信息、topic数据、偏移量等等)
假设你的producer 或者 consumer 的量非常大,namesrv 扛不住了,这个时候增加namesrv的节点即可。 namesrv的节点越多,你命中那个失败的namesrv的概率就会降低。
除了broker,剩下3个的集群都是无状态的。 broker才是真正的核心。
消息队列的作用
说点大家都知道的 消息队列的作用
- 解耦
- 削峰填谷
- 异步处理
- 分布式事务-中间协调
举个例子 比如解耦
各个服务之间从原来的强耦合,加入了消息队列后,支撑成功后,扔到消息队列里面,剩下的服务谁需要处理这个消息,谁来订阅即可,减少了下订单的时长。
Kafka VS RocketMQ VS RabbitMQ
从网上找的一个图,个人认为非常不错,请移步
戳这里: Kafka VS RocketMQ VS RabbitMQ
另外官网上 有关于 ActiveMQ VS Kafka VS RocketMQ, 请移步 : 戳这里