SpringAlibaba之RocketMQ总结

·  阅读 89

@[toc] RocketMQ消息中间件使用比较简单,官方提供的各种使用模式以及SpringCloudAlibaba支持的SpringCloudStream的RocketMQ支持,使用示例都整理到了gitee的示例工程当中。gitee地址:gitee.com/tearwind/SC… rocketmq.apache.org/docs/quick-…

一. 为什么选RocketMQ:

官方的故事: 最开始用的ActiveMQ,但是,当用到的队列和虚拟topic上升后,ActiveMQ的IO很快达到了瓶颈。解决不了后,开始使用Kafka,但是Kafka无法满足低延迟、高可用的需求。于是有了RocketMQ。RocketMQ支持阿里的海量数据、高并发场景,并且端到端的延迟非常短,横向扩展能力也很强。

二. RocketMQ的部署结构

包含Producer、nameServer、Broker、Consumer,都可以作为集群。整体部署结构如下图:

RocketMQ整体部署结构 其中NameServer和Broker Server需要独立启动。其启动脚本都在下载的安装包中。NameServer的启动脚本是bin/mqnamesrv,Broker Server的启动脚本是: sh bin/mqbroker -n localhost:9876,集群工作时,需要先启动Name Server,再启动 Broker Server
Producer和Consumer的客户端代码中只需要关心Name Server。
整个网络的工作机制是这样的:

  • Name Server是一个几乎无状态的节点,可集群部署,节点之间无任何信息同步。
  • Broker集群分为Master和Slaver。一个Master可以对应多个Slaver,但是一个Slaver只能对应一个Master。Master与Slaver的对应关系通过指定相同的BrokerName,不同的BrokerId来定义,BrokerId为0表示Master,非0表示Slave。Master可以部署多个,每个Broker与Name Server集群中的所有节点建立长连接,定时注册Topic信息到所有Name Server。
  • Producer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server获取Topic路由信息,并向提供Topic服务的Master建立长连接,且定时向Master发送心跳。Producer完全无状态,可集群部署。
  • Consumer与Name Server集群中的其中一个节点(随机选择)建立长连接,定期从Name Server获取Topic路由信息,并向提供Topic服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer即可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker配置决定。
  • 最后,RocketMQ没有RabbitMQ那样的控制台页面,只提供了一个mqadmin指令协助进行管理。

三. RocketMQ的特性

  1. RocketMQ是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式特点。
  2. Producer、Consumer、队列都可以分布式。因此整体的扩展性非常灵活。
  3. Producer向一些队列轮流发送消息,队列集合称为Topic,Comsumer如果做广播消费,则一个Consumer实例消费这个Topic对应的所有队列。如果做集群消费,则多个Consumer实例平均消费这个topic对应的队列集合。
  4. 能够保证严格的消息顺序。

关于消息的顺序,RocketMQ有比Kafka更严格的消息顺序。RocketMQ的消息有序性分为全局顺序和局部顺序。
- 全局顺序 对于指定的一个 Topic,所有消息按照严格的先入先出(FIFO)的顺序进行发布和消费。 适用场景:性能要求不高,所有的消息严格按照 FIFO 原则进行消息发布和消费的场景 - 分区顺序 对于指定的一个 Topic,所有消息根据 sharding key 进行区块分区。 同一个分区内的消息按照严格的 FIFO 顺序进行发布和消费。 Sharding key 是顺序消息中用来区分不同分区的关键字段,和普通消息的 Key 是完全不同的概念。 适用场景:性能要求高,以 sharding key 作为分区字段,在同一个区块中严格的按照 FIFO 原则进行消息发布和消费的场景。 5. 提供丰富的消息拉取模式,推送消费、拉取消费。 6. 高效的订阅者水平扩展能力 数据与索引分开存储,Producer和Consumer不会有资源竞争关系,有效降低文件资源、IO资源、内存资源的消耗 7. 实时的消息订阅能力 8. 亿级消息堆积能力 Rocket能保证消息可靠性,只要机器和硬盘没坏,消息就不会丢失(异步刷盘的方式可能有少量的数据丢失)。并且RocketMQ没有内存Buff的概念,RocketMQ的队列都是用磁盘持久化,数据定期清除,所以不会出现数据丢失的情况。 9. 较少的依赖 10. 支持Broker端的消息过滤。即Consumer可上传一段代码到Broker,对消息进行过滤。这样可以减少Consumer接收到的消息。当然Broker的压力会加大。
11. 支持Batch提交,增加系统吞吐量。 12. 支持分布式事务。

四、RocketMQ使用的基本流程

4.1 消息发送者 MQProducer

MQProducer是RocketMQ消息发送者的通用接口,发送消息的基本流程都是先实例化一个MQProducer对象,先调用start()方法 进行初始化,然就就通过send方法发送消息。 官方提供的一个实现类是DefaultMQProducer,继承自ClientConfig对象,实例化的时候需要注意下他的NamesrvAddr属性,这个属性是指定目标RocketMQ的Name Server。这个属性可以通过setNamesrvAddr方法手动给指定,但是DefaultMQProducer在初始化时,会通过一个NameServerAddressUtils类来设置默认值。

public static String getNameServerAddresses() {
        return System.getProperty(MixAll.NAMESRV_ADDR_PROPERTY, System.getenv(MixAll.NAMESRV_ADDR_ENV));
    }
//MixAll里的属性定义
public static final String NAMESRV_ADDR_ENV = "NAMESRV_ADDR";
public static final String NAMESRV_ADDR_PROPERTY = "rocketmq.namesrv.addr";
复制代码

所以,可以通过配置rocketmq.namesrv.addr属性或者配置NAMESRV_ADDR环境变量来指定NamesrvAddr属性。

4.2 消息消费者 MQConsumer

MQConsumer是Rocket消息消费者的通用接口,消费者模块分为拉取消费和推送消费两种模式。
其中,推模式消费的接口是MQPushConsumer,提供一个默认实现类DefaultMQPushConsumer。 拉模式消费的接口有两个,MQPullConsumer和LitePullConsumer,也都分别提供了实现类DefaultMQPullConsumer和DefaultLitePullConsumer。其中DefaultMQPullCOnsumer目前已被标识为过期。他们同样都是继承于ClientConfig类的。这两个实现类的区别在官网上没有找到,目前的官网示例也都还是用的DefaultMQPullConsumer。只是在百度上找到一个说明,RocketMQ引入LitePullConsumer可以解决以下问题

(1) Support consume messages in subscribe way with auto rebalance.

(2) Support consume messages in assign way with no auto rebalance support.
(3) Add seek/commit offset for a specified message queue.

五. RocketMQ的消息格式

RocketMQ的消息分为Topic、Tag、MsgId、Content四个部分。相比Kafka,多了一个tag的概念。

  • 官方的建议是一个应用尽可能就用一个Topic。
  • Tag可以由应用自由设置,但是要注意只有生产者在发送消息时设置了tag,消费者才能用tag通过Broker做消息过滤。并且这个过滤是由消费者提交,在Broker端执行的,可以有效减少消费者端的压力。
  • MsgId这个用来做为业务层面的消息唯一标识,业务层面务必保证MsgId的唯一性。RocketMQ会为每个消息建立索引,应用可以通过Topic+MsgId查询消息内容,以及消息消费情况。另外要注意,RocketMQ在消费过程中,无法保证等幂,即消息可能被重复消费,所以需要应用来自行剔重,而剔重的标准,就是这个MsgId。

六. RocketMQ-externals

虽然RocketMQ没有提供控制台,但是在RocketMQ-externals仓库中开发了有一个控制台。仓库地址:github.com/apache/rock… RocketMQ社区的项目,里面有大量的RocketMQ与其他框架整合的模块,可以随时参考下。
而其中的rocketmq-console模块就是一个RocketMQ的图形化控制台。
这里面RocketMQ-MySQL模块可以将mysql的binlog以json方式发送到RocketMQ,这样,其他系统可以从RocketMQ及时消费到MySQL的数据变化。

七. RocketMQ的其他资料

RocketMQ集群支持权限控制:github.com/apache/rock…
RocketMQ集群可使用Dledger搭建高可用容灾集群: github.com/apache/rock…
github.com/apache/rock…
RocketMQ运维管理:单Mster、多Master、多Maseter多Slave异步复制,多Master多Slavet同步双写以及Mqadmin工具使用:github.com/apache/rock…

分类:
后端
标签:
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改