消息队列的主要作用是对系统进行异步、削峰、解耦等,在日常开发中使用非常广泛。基于市面上几款消息队列,常见有:rabbitmq, activemq, rocketmq, kafka, Pulsar等,各有侧重,技术选型需根据自身系统业务定型。但基于国内市场,以及编程语言的占有率,阿里巴巴开源的RocketMQ无论在开发习惯,使用习惯以及设计思维上,都更符合国内系统,且经受了多次双十一的考验,整合了上述多款消息队列的优点。本系列将从0开始学习rocketMQ的搭建及使用,并给出部分场景解决方案。
1,版本
如上图,截止目前2024/11/12,rocketmq已迭代至版本5.3.1。RocketMQ · 官方网站 | RocketMQ 将版本区分为两个大版本,5.0和4.x,区别较大,对于普通开发来讲,主要区别包括但不限于:延迟消息等级设置、混合集群模式、客户端语言限制等。目前仍有很多企业使用4.x版本,先基于4.x版本学习基础部署和理论,后续在此基础上学习5.0版本。
2,基本概念
2.1,消息系统模型
生产者(Producer):负责发送消息。一般由业务系统生产消息,将消息给生产者,生产者会把业务应用系统里产生的消息发送到broker服务器。RocketMQ提供多种发送方式,同步发送、异步发送、顺序发送、单向发送。
消费者(Consumer):负责接受消息,也称消费消息。一般是业务系统接受消息后异步消费。从用户应用的角度而言提供了两种消费形式:拉取式消费、推动式消费。
消息主题(Topic):表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。
2.2,部署模型
NameServer:注册中心,用于存储各Broker的节点位置和状态信息,以及topic与MessageQueue的路由关系,可理解为nacos,主要作用是:
1,Broker管理。存储各Broker节点位置,发送心跳检查Broker是否存活;
2,路由信息管理。存储topic与实际存储消息的messageQueue的路由关系,便于消息的投递与查找。
生产者和消费者与NameServer建立长连接,定期从NameServer中获取Broker和topic的路由信息,再与Broker的主节点建立长连接,将消息发送到对应的MessageQueue,或者直接从对应的MessageQueue获取消息。Broker与NameServer建立长连接,定期将Topic路由信息注册或更新至NameServer存储。
Broker:消息的中间服务器,用于存储消息。Topic是个逻辑概念,实际存储消息的是MessageQueue。消费者将消息根据Topic分类,发送至对应的MessageQueue,MessageQueue是FIFO的有序序列。
消费者的推模式是Broker将消息从MessageQueue中推送给消费者,拉模式是消费者从MessageQueue中获取消息。
拓展后的部署和消息模型架构图如下:
如上图所示,当使用集群架构后,Broker会将MessageQueue放在不同的Broker服务中,以保证高可用性。消费端,通过消费者组,提高消费能力,可根据业务水平拓展。
注意:4.x版本中,一个消费者可消费多个MessageQueue的消息,但一个MessageQueue只能由一个消费者消费,具体由哪个消费者消费,则依据消费者订阅的主题匹配。
3,Rocketmq项目结构
rocketmq本质上是一个spingboot项目,所以在运行时,需要java虚拟机,并需要对JVM参数做调整,再启动该项目即可。JVM参数调整与工作中对项目的JVM调优相同。这也验证前面所说,对开发更易懂易上手。
根据版本图也可看出,下载分为源码和linux运行版。下载Binary至服务器并解压,得到如下目录:
benchmark:压测脚本
bin:执行脚本,启动脚本
根据前文可知,启动需要启动nameServer和Broker。
启动nameServer:执行mqnamesrv脚本,其内部会执行runserver.sh。修改runserver.sh文件内容,调整JVM参数。如下图,根据对应的JDK版本及服务器内存,修改合适的JVM参数。默认4G堆内存。
启动Broker:执行mqbroker脚本,其内部会执行runbroker.sh。修改runbroker.sh文件内容,调整JVM参数。如下图,根据对应的JDK版本及服务器内存,修改合适的JVM参数。默认8G堆内存。
conf:配置文件,虚拟机参数调整,nameserver/broker参数调整,常见部署方式配置文件案例等
lib:依赖jar包