前言
为什么要学习RocketMQ?
RocketMQ是一个队列模型的的消息中间件,具有高性能、高可靠、高实时、分布式等特点。
其主要特点如下:
- 生产者、消费者、队列都可以分布式。
- 能够保证严格的消息顺序。
- 提供丰富的消息拉取模式。
- 高效的订阅者水平扩展能力。
- 实时的消息订阅机制。
- 亿级消息堆积能力。
- 较少的依赖。
RocketMQ的基本原理就是生产者(Producer)向一些队列轮流发送消息,队列集合称为Topic,消费者(Consumer)如果做广播消费,则一个消费者实例消费这个Topic对应的所有队列,如果做集群消费,则多个消费者实例平均消费这个topic对应的队列集合。
消息中间件收发消息的典型模型如下图:
好吧,我承认前言太官方了。我们来看下正文关于RocketMQ的一些特点吧。
正文
RocketMQ术语。
先介绍RocketMQ的几个术语。
Producer
消息生产者,生产者的作用就是将消息发送到Broker(MQ),生产者本身既可以产生消息。也可以对外提供接口,由外部应用来调用接口,再由生产者将收到的消息发送到 Broker(MQ)。
Producer Group
生产者组,一般来说多个发送同一类消息的生产者称之为一个生产者组。
Consumer
消息消费者,消费 Broker(MQ) 上的消息的应用程序就是消费者,消息的处理取决于业务。
Consumer Group
消费者组,和生产者类似,消费同一类消息的多个 consumer 实例组成一个消费者组。
Topic
Topic 是一种消息的逻辑分类,比如说你有支付订单类的消息,也有奖品抽取类的消息,那么就需要进行分类,一个是支付订单 Topic 存放支付订单相关的消息,一个是奖品抽取 Topic 存储抽取奖品结果相关的消息。
Message
Message 是消息的载体。一个 Message 必须指定 topic。Message 还有一个可选的 tag 设置,以便消费者可以基于 tag 进行过滤消息。也可以添加额外的键值对等。
Tag
标签可以被认为是对 Topic 进一步细化。一般在相同业务模块中通过引入标签来标记不同用途的消息。
Broker
Broker 是 RocketMQ系统的主要角色。Broker 接收来自生产者的消息,储存以及为消费者拉取消息的请求做好准备。
Name Server
Name Server 为 producer 和 consumer 提供路由信息。
对于上面的几个概念的理解,可以从一封邮件的发送入手,认为发信人是Producer,收信人为Consumer,Message,Topic和Tag分别指信的内容,信的分类规则等,Broker就相当于邮局了。
RocketMQ集群架构
再来看一下RocketMQ常用的物理部署结构。(生产环境常用的RocketMQ集群架构)
RocketMQ的集群特点如下:
Name Server是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master,Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server。
Producer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。要注意Producer并不能和 Broker Slave建立连接。
Consumer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。
Broker Master和 Broker Slave之间会进行数据同步,即Data Sync。
数据复制主要有两种:
①同步复制 SYNC_MASTER
master 和 slave 都写成功后返回成功状态。好处是如果master出故障,slave上有全部备份,容易恢复。缺点是增大延迟,降低吞吐量。
②异步复制 ASYNC_MASTER
只要 master 写成功就返回成功状态。好处是低延迟、高吞吐,缺点是如果 master 出故障,数据没有写入 slave,就会有丢失。
master或者 slave在返回处理成功消息时,需要将数据持久化(写入磁盘)。称之为MQ的刷盘。
刷盘策略也有两种:
①同步刷盘 SYNC_FLUSH
返回成功状态时,消息已经被写入磁盘。
消息写入内存后,立即通知刷盘线程,刷盘完成后,返回消息写成功的状态。
②异步刷盘 ASYNC_FLUSH
返回成功状态时,消息只是被写入内存,写操作返回快,吞吐量达,当内存里的消息积累到一定程度时,统一出发写磁盘动作,快速写入。
RocketMQ部署模式
根据上面的描述,我们也大致可以知道RocketMQ通常有3种部署模式。
单master部署
简单来说就是环境上就一台RocketMQ,一般自己开发研究学习会用这种模式。这种部署明显的缺点就是MQ宕机后系统就会挂掉。所以不用于测试或生产环境。
多master部署
就是环境上有多台RocketMQ,都充当master的角色。这种方式部署,如果有一台MQ挂掉或者重启,并不会对整个应用系统造成影响。但是该节点MQ宕机期间,未消费的MQ消息是无法被消费的,只有等该节点故障排除后才能恢复正常。如果无法恢复,则会造成RocketMQ消息的永久丢失。
这种方式,如果是使用的异步刷盘,则故障发生并恢复正常后可能丢失部分消息(写入内存没来得及写入磁盘的消息);如果同步刷盘,则不会出现此情况,但同步刷盘会对MQ的响应速度造成一些影响。
多master 多slave部署
根据刷盘策略和数据复制策略。我们知道这种部署方式基本有四种组合策略。同步复制同步刷盘明显是效率最差但最安全的,异步复制异步刷盘明显是效率最好但最不安全的。
一般情况下,我们比较常用的是异步刷盘+同步复制的模式。这样即使master 宕机,同步复制的slave也能保证把消息写入磁盘。同时使用异步刷盘策略,因为写入磁盘本身是应用系统中耗时的一个操作,先写入内存,随后写入磁盘,可以保证MQ的响应速度。
结语
这一篇文章简单介绍了RocketMQ的一些性质和特点,了解这些特点,才能更好的掌握RocketMQ,后面我们会搭建一个RocketMQ服务进行下学习,并对我们的调用代码做些优化,封装为自己的一个小小工具类。
回答下最开始的问题,因为我们公司用到了。