消息队列RocketMQ实战与原理


消息队列

消息队列(Message Queue, MQ)常用在分布式系统中,用于异步、削峰、解耦等。

当前主流的消息队列产品包括:
Apache Kafka: 以其高性能、低延迟和高可靠性著称,特别适合大数据流处理和事件驱动的应用场景。

RabbitMQ: 基于AMQP协议,提供了丰富的特性和良好的社区支持,适用于多种应用场景,尤其是企业级项目。

RocketMQ: 阿里巴巴开源的一款分布式消息中间件,具有高吞吐量、低延迟的特点,适用于金融级别的交易系统。

NATS: 轻量级、高速的消息传输系统,适用于微服务架构和物联网场景。

RocketMQ发展历程

在这里插入图片描述
2007年,淘宝实施了“五彩石”项目,“五彩石”用于将交易系统从单机变成分布式,也是在这个过程中产生了阿里巴巴第一代消息引擎——Notify。2011年,阿里巴巴在研究了Kafka的整体机制和架构设计之后,基于Kafka的设计使用Java进行了完全重写并推出了MetaQ 1.0版本,主要是用于解决顺序消息和海量堆积的问题。而在2012年,阿里巴巴发现MetaQ原本基于Kafka的架构在阿里巴巴如此庞大的体系下很难进行水平扩展,所以在2012年的时候就开发了RocketMQ 3.0版本。在2015年,又基于RocketMQ开发了阿里云上的Aliware MQ和Notify 3.0。在2016年的时候,阿里巴巴将RocketMQ的内核引擎捐赠给了Apache基金会。


RocketMQ架构

示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。

  • Name Server在RocketMQ中充当注册中心的角色。是一个几乎无状态节点,可集群部署,节点之间无任何信息同步。
  • Broker是RocketMQ中真正存储消息的地方。部署相对复杂,Broker可以部署多Master、多Slave。每个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

  1. 具有高性能、高可靠、高实时、分布式特点。
  2. 能够保证严格的消息顺序
  3. 提供丰富的消息拉取模式
  4. 高效的订阅者水平扩展能力
  5. 实时的消息订阅机制
  6. 亿级消息堆积能力

消费模型

RocketMQ支持集群消费和广播消费模式。

集群消费

消息会投递到消费者集群中的一个节点进行消费。
在这里插入图片描述

广播消费

消息会投递到所有消费者节点进行消费。
在这里插入图片描述


关键设计原理

消息存储

RocketMQ的Broker Strore从Mysql innodb上借鉴了许多,采用了一种基于日志的存储方式,将消息以顺序写入的方式追加到文件中,从而实现高性能的消息存储和读取。
在这里插入图片描述

RocketMQ的消息存储是由consume queue和commit log配合完成的。
consume queue是消息的逻辑队列,相当于字典的目录,用来指定消息在物理文件commit log上的位置。
Commit Log的消息是真实的消息数据,存储单元长度不固定,文件顺序写,随机读。消息的存储结构如下表所示,按照编号顺序以及编号对应的内容依次存储。
在这里插入图片描述
这种存储设计,最大的好处是写速度很快,多toipc共享顺序写commit log,又平衡了topic维度拆分的读操作。
**而读性能优化方面,使用了二次查询(topic queue log -> commit log)**有所折损性能,使用了零拷贝、客户端批量查(默认1k条消息)以提高转盘命中率。

消息订阅

RocketMQ消息订阅有两种模式,一种是Push模式,即MQServer主动向消费端推送;另外一种是Pull模式,即消费端在需要时,主动到MQServer拉取。但在具体实现时,Push和Pull模式都是采用消费端主动拉取的方式。之所以这样设计是为了降低MQServer在集群规模较大的情况下的可能会对可靠性有所影响。

在这里插入图片描述
消费端的Push模式实际上是通过长轮询的模式来实现的,长轮询是利用HTTP协议的特性,让客户端能够长时间保持一个请求不被关闭,直到服务器有新数据推送为止。这样可以实现近乎实时的推送效果。好处是数据实时性高的同时降低了Server的压力。

顺序消息

RocketMQ在进行消息发送时,可以按照业务逻辑选择对应的消息队列进行发送,保证对应的一批消息发到同一个队列中,即可保证消息的顺序。

 producer.send(message, new MessageQueueSelector() {
     @Override
     public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
         Long id = (Long) arg;
         int index = (int) (id % mqs.size());
         return mqs.get(index);
     }
 }, args);
  • 20
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java码农杂谈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值