RocketMQ基础

  • RocketMQ是什么
  • RocketMQ的作用、优缺点
  • RocketMQ安装、测试
  • 各角色介绍
  • RocketMQ结构示意图
  • RocketMQ集群搭建
  • 集群监控平台搭建 rocketmq_console
  • RocketMQ JAVA消息发送示例


RocketMQ是什么

  1. MQ(MessageQueue)消息队列是一种“先进先出”的数据结构;
  2. RocketMQ是分布式消息中间件

RocketMQ的作用、优缺点

  1. 应用解耦
    系统的耦合性越高,容错性就越低。以电商应用为例,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统除了故障或者因为升级等原因暂时不可用,都会造成下单操作异常,影响用户使用。
  2. rocketmq window broker启动闪退 no resource file with name store found_消息队列

  3. 使用消息队列解耦合,系统的耦合就会降低。比如物流系统发生故障,需要几分钟才能修复,在这段时间内,物流系统要处理的数据会暂存在消息队列中,用户的下单操作正常完成。当物流系统恢复后,处理存在消息队列的订单消息即可,用户是感知不到物流系统发生过故障。
  4. rocketmq window broker启动闪退 no resource file with name store found_长连接_02

  5. 流量削峰
    应用系统如果遇到系统请求流量的瞬间猛增,有可能会将系统直接压垮。消息队列可以讲大量请求缓存起来,分散处理,能大大的提高系统的可用性。一般情况下,为了保证系统的稳定性,如果系统负载超过阈值,就会阻止用户请求,比如请求等待等会影响用户体验,而如果使用消息队列将请求缓存起来,等系统处理完毕后通知用户下单完毕,这样好过不能下单。
    从经济方面考虑,业务系统正常时段的QPS如果是1000,流量高峰期是10000,短时的高QPS显然不适合使用高配置高性能的服务器,此时使用MQ进行流量削峰更合算
  6. rocketmq window broker启动闪退 no resource file with name store found_长连接_03

  7. 3.数据分发
  8. rocketmq window broker启动闪退 no resource file with name store found_长连接_04

  9. 通过消息队列可以让数据在多个系统之间进行流通。数据的生产方不需要关心谁来使用数据,只需要将数据发送到MQ,数据使用方直接订阅MQ消费消息即可
  10. rocketmq window broker启动闪退 no resource file with name store found_长连接_05

优点:解耦、削峰、数据分发
缺点:
系统可用性降低。系统引入的MQ依赖,一旦MQ宕机,业务就会完全进行不了(如何保障MQ的高可 用)
系统的复杂度提高。引入MQ之前各个系统之间是同步调用的关系,现在使用MQ进行异步调用(如何保障消息没有被重复消费?如何处理消息丢失情况?怎么保障消息传递的顺序性)
一致性问题。A系统处理完业务,通过MQ给B/C/D三个系统发消息数据,如果B/C系统处理成功,D系统处理失败了(如何保障消息数据处理的一致性?)

RocketMQ安装、测试

快速入门

安装RocketMQ

  • 1、上传到linux服务器、解压RocketMQ的zip包
    unzip rocketMQ.zip
  • 2、目录介绍
    bin/:启动脚本
    conf/:配置文件
    lib/:依赖的jar包

启动RocketMQ

  • 1、启动NameServer
  • 进入bin目录:cd /usr/local/rocketMQ/rocketmq-all-4.7.1-bin-release/bin/
  • 启动NameSrv: nohup sh mqnamesre &
  • 查看启动日志: tail -f /root/logs/rocketmqlogs/namesrv.log

rocketmq window broker启动闪退 no resource file with name store found_发送消息_06

  • 2、启动Broker
  • 进入bin目录:cd /usr/local/rocketMQ/rocketmq-all-4.7.1-bin-release/bin/
  • 启动Broker: nohup sh mqbroker -n 172.23.22.191:9876 &
  • 查看启动日志: tail -f /root/logs/rocketmqlogs/broker.log

测试RocketMQ

  • 1、发送消息
  • 设置环境变量:export NAMESRV_ADDR=172.23.22.191:9876
  • 使用提供Producer发送消息:
    sh tools.sh org.apache.rocketmq.example.quickstart.Producer
  • 2、消费消息
  • 设置环境变量:export NAMESRV_ADDR=172.23.22.191:9876
  • 使用提供Consumer发送消息:
    sh tools.sh org.apache.rocketmq.example.quickstart.Consumer

关闭RocketMQ

  • 1、关闭NameServer
  • sh bin/mqshutdown namesrv
  • 2、关闭Broker
  • sh bin/mqshutdown broker

各角色介绍

Producer: 消息的发送者 类似于:发信者
Consumer:消息的接收者 类似于:收信者
Broker: 暂存与传递消息 类似于:邮局
NameServer: Broker的管理者 类似于:邮局管理机构
Topic: 区分消息的种类;一个发送者可以发送消息给一个或者多个Topic;一个消息的接收者可以订阅一个或者多个Topic消息

RocketMQ结构示意图

rocketmq window broker启动闪退 no resource file with name store found_消息队列_07

  • 集群工作流程:
  • 1、启动Namesrv,Namesrv起来后监听端口,等待Broker、Produer、Consumer连上来,相当于一个路由控制中心。
  • 2、Broker启动,跟所有的Namesrv保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有topic信息。注册成功后,namesrv集群中就有Topic跟Broker的映射关系。
  • 3、收发消息前,先创建topic,创建topic时需要指定该topic要存储在哪些Broker上。也可以在发送消息时自动创建Topic。
  • 4、Producer发送消息,启动时先跟Namesrv集群中的其中一台建立长连接,并从Namesrv中获取当前发送的Topic存在哪些Broker上,然后跟对应的Broker建立长连接,直接向Broker发消息。
  • 5、Consumer跟Producer类似。跟其中一台Namesrv建立长连接,获取当前订阅Topic存在哪些Broker上,然后直接跟Broker建立连接通道,开始消费消息。

RocketMQ集群搭建方式

  • Namesrv是一个无状态节点,可集群部署,节点之前无任何的信息同步。
  • Broker部署相对复杂,Broker分为Master与Slave,一个Master可以对应多个Slave,但是一个Slave只能对应一个Master。Master与Slave的对应关系通过指定相同的BrokerName,不同的BrokerId来定义。BrokerID为0表示Master,非0表示Slave。Master也可以部署多个。每个Broker与NameSrv集群中的所有节点建立长连接,定时上报心跳注册IP、Topic等信息到NameSrv。
  • Produce与Namesrv集群中的随意几个节点建立长连接,定期从Namesrv中取Broker、Topic信息,并向提供Topic的服务的Master建立长连接,且定时向Master发送心跳。Produce也是无状态的,可以集群部署。
  • Consumer与Namesrv集群中的随意几个节点建立长连接,定期从Namesrv中取Broker、Topic信息,并向提供Topic的服务的Master、Slave建立长连接,且定时向Master、Slave发送心跳。Consumer既可以从Master订阅消息,也可以从Slave订阅消息,由Broker配置决定。Consumer也是无状态的,可以集群部署

RocketMQ集群搭建

  • RocketMQ集群模式
  • 单Master模式:这种方式风险较大,一旦Broker重启或者宕机时,会导致整个服务不可用
  • 多Master模式:一个集群无Slave,全是Master
    优点:配置简单,单个Master宕机或者重启对应用无影响
    缺点:单机器宕机期间,消息不能被消费,消息实时性收到影响
  • 多Master模式多Slave模式(异步): 每个Master配置一个Slave,有多对Master-Slave,采用异步复制方式,主备有短暂消息延迟
  • 多Master模式多Slave模式(同步): 每个Master配置一个Slave,有多对Master-Slave,采用同步复制方式,消息无延迟,只有主备都写成功才响应成功。

RocketMQ双主双从集群搭建

rocketmq window broker启动闪退 no resource file with name store found_长连接_08

  • RocketMQ双主双从集群工作流程
    1、启动NameSrv,监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。
    2、Broker启动,跟所有的NameSrv保持长连接,定时发送心跳。心跳包中包含当前Broker信息(IP+端口)以及存储所有Topic信息。注册成功后,NameSrv集群中就有了Topic跟Broker的映射关系。
    3、收发消息前,先创建Topic,创建Topic时需要制定该Topic需要存储在哪些Broker上,也可以在发送消息时自动创建Topic。
    4、Producer发送消息,启动时先跟Namesrv集群中的其中一台建立长连接,并从NameSrv中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Borker建立长连接发送消息。
    5、Consumer跟Producer类似,先跟Namesrv集群中的其中一台建立长连接,获取当前订阅的Topic存在哪些Broker上,然后与队列所在的Borker建立长连接发送消息。

服务器环境

rocketmq window broker启动闪退 no resource file with name store found_长连接_09


创建消息存储路径
 mkdir /usr/local/rocketmq/store
 mkdir /usr/local/rocketmq/store/commitlog
 mkdir /usr/local/rocketmq/store/consumequeue
 mkdir /usr/local/rocketmq/store/index
mkdir /usr/local/rocketmq/store/slave
 mkdir /usr/local/rocketmq/store/slave/commitlog
 mkdir /usr/local/rocketmq/store/slave/consumequeue
 mkdir /usr/local/rocketmq/store/slave/indexmaster1配置-IP1
 vi /usr/local/rocketMQ/rocketmq-all-4.7.1-bin-release/conf/2m-2s-sync/broker-a.properties#所属集群名字
 brokerClusterName=rocketmq-cluster
 #broker名字 此处不同的配置文件填写不一样
 brokerName=broker-a
 #brokerID 0标识Master 非0标识Slave
 brokerId=0
 #nameserver地址,分号分隔
 namesrvAddr=172.23.22.191:9876;172.23.23.249:9876
 #在发送消息时,自动创建服务器不存在的Topic,默认创建的队列数
 defaultTopicQueueNums=4
 #是否允许Broker自动创建Topic
 autoCreateTopicEnable=true
 #是否允许Broker自动创建订阅组
 autoCreateSubscriptionGroup=true
 #Broker 对外的监听端口
 listenPort=10911
 #删除文件时间点 凌晨4点
 deleteWhen=04
 #文件保留时间 默认48小时
 fileReservedTime=48
 #commitLog每个文件的大小默认1G
 mapedFileSizeCommitLog=102400
 #ConsumerQueue每个文件默认存30W条,根据业务调整
 mapedFileSizeConsumerQueue=300000
 #存储路径
 storePathRootDir=/usr/local/rocketmq/store
 #commitlog存储路径
 storePathCommitLog=/usr/local/rocketmq/store/commitlog
 #消息队列存储路径
 storePathConsumerQueue=/usr/local/rocketmq/store/consumequeue
 #消息index存储路径
 storePathIndex=/usr/local/rocketmq/store/index
 #checkpoint存储路径
 storeCheckpoint=/usr/local/rocketmq/store/checkpoint
 #abort存储路径
 abortFile=/usr/local/rocketmq/store/abort
 #broker角色
 #ASYNC_MASTER 异步复制Master
 #SYNC_MASTER 同步复制Master
 #SLAVE
 brokerRole=SYNC_MASTER
 #刷盘方式
 #ASYNC_FLUSH 异步刷盘
 #SYNC_FLUSH 同步刷盘
 flushDiskType=SYNC_FLUSHslave2配置-IP1
 vi /usr/local/rocketMQ/rocketmq-all-4.7.1-bin-release/conf/2m-2s-sync/broker-b-s.properties#所属集群名字
 brokerClusterName=rocketmq-cluster
 #broker名字 此处不同的配置文件填写不一样
 brokerName=broker-b
 #brokerID 0标识Master 非0标识Slave
 brokerId=1
 #nameserver地址,分号分隔
 namesrvAddr=172.23.22.191:9876;172.23.23.249:9876
 #在发送消息时,自动创建服务器不存在的Topic,默认创建的队列数
 defaultTopicQueueNums=4
 #是否允许Broker自动创建Topic
 autoCreateTopicEnable=true
 #是否允许Broker自动创建订阅组
 autoCreateSubscriptionGroup=true
 #Broker 对外的监听端口
 listenPort=11011
 #删除文件时间点 凌晨4点
 deleteWhen=04
 #文件保留时间 默认48小时
 fileReservedTime=48
 #commitLog每个文件的大小默认1G
 mapedFileSizeCommitLog=102400
 #ConsumerQueue每个文件默认存30W条,根据业务调整
 mapedFileSizeConsumerQueue=300000
 #存储路径
 storePathRootDir=/usr/local/rocketmq/store/slave
 #commitlog存储路径
 storePathCommitLog=/usr/local/rocketmq/store/slave/commitlog
 #消息队列存储路径
 storePathConsumerQueue=/usr/local/rocketmq/store/slave/consumequeue
 #消息index存储路径
 storePathIndex=/usr/local/rocketmq/store/slave/index
 #checkpoint存储路径
 storeCheckpoint=/usr/local/rocketmq/store/slave/checkpoint
 #abort存储路径
 abortFile=/usr/local/rocketmq/store/slave/abort
 #broker角色
 #ASYNC_MASTER 异步复制Master
 #SYNC_MASTER 同步复制Master
 #SLAVE
 brokerRole=SLAVE
 #刷盘方式
 #ASYNC_FLUSH 异步刷盘
 #SYNC_FLUSH 同步刷盘
 flushDiskType=ASYNC_FLUSHmaster2配置-IP2
 vi /usr/local/rocketMQ/rocketmq-all-4.7.1-bin-release/conf/2m-2s-sync/broker-a.properties#所属集群名字
 brokerClusterName=rocketmq-cluster
 #broker名字 此处不同的配置文件填写不一样
 brokerName=broker-b
 #brokerID 0标识Master 非0标识Slave
 brokerId=0
 #nameserver地址,分号分隔
 namesrvAddr=172.23.22.191:9876;172.23.23.249:9876
 #在发送消息时,自动创建服务器不存在的Topic,默认创建的队列数
 defaultTopicQueueNums=4
 #是否允许Broker自动创建Topic
 autoCreateTopicEnable=true
 #是否允许Broker自动创建订阅组
 autoCreateSubscriptionGroup=true
 #Broker 对外的监听端口
 listenPort=10911
 #删除文件时间点 凌晨4点
 deleteWhen=04
 #文件保留时间 默认48小时
 fileReservedTime=48
 #commitLog每个文件的大小默认1G
 mapedFileSizeCommitLog=102400
 #ConsumerQueue每个文件默认存30W条,根据业务调整
 mapedFileSizeConsumerQueue=300000
 #存储路径
 storePathRootDir=/usr/local/rocketmq/store
 #commitlog存储路径
 storePathCommitLog=/usr/local/rocketmq/store/commitlog
 #消息队列存储路径
 storePathConsumerQueue=/usr/local/rocketmq/store/consumequeue
 #消息index存储路径
 storePathIndex=/usr/local/rocketmq/store/index
 #checkpoint存储路径
 storeCheckpoint=/usr/local/rocketmq/store/checkpoint
 #abort存储路径
 abortFile=/usr/local/rocketmq/store/abort
 #broker角色
 #ASYNC_MASTER 异步复制Master
 #SYNC_MASTER 同步复制Master
 #SLAVE
 brokerRole=SYNC_MASTER
 #刷盘方式
 #ASYNC_FLUSH 异步刷盘
 #SYNC_FLUSH 同步刷盘
 flushDiskType=SYNC_FLUSH

slave1 配置-IP2

#所属集群名字
 brokerClusterName=rocketmq-cluster
 #broker名字 此处不同的配置文件填写不一样
 brokerName=broker-a
 #brokerID 0标识Master 非0标识Slave
 brokerId=1
 #nameserver地址,分号分隔
 namesrvAddr=172.23.22.191:9876;172.23.23.249:9876
 #在发送消息时,自动创建服务器不存在的Topic,默认创建的队列数
 defaultTopicQueueNums=4
 #是否允许Broker自动创建Topic
 autoCreateTopicEnable=true
 #是否允许Broker自动创建订阅组
 autoCreateSubscriptionGroup=true
 #Broker 对外的监听端口
 listenPort=11011
 #删除文件时间点 凌晨4点
 deleteWhen=04
 #文件保留时间 默认48小时
 fileReservedTime=48
 #commitLog每个文件的大小默认1G
 mapedFileSizeCommitLog=102400
 #ConsumerQueue每个文件默认存30W条,根据业务调整
 mapedFileSizeConsumerQueue=300000
 #存储路径
 storePathRootDir=/usr/local/rocketmq/store/slave
 #commitlog存储路径
 storePathCommitLog=/usr/local/rocketmq/store/slave/commitlog
 #消息队列存储路径
 storePathConsumerQueue=/usr/local/rocketmq/store/slave/consumequeue
 #消息index存储路径
 storePathIndex=/usr/local/rocketmq/store/slave/index
 #checkpoint存储路径
 storeCheckpoint=/usr/local/rocketmq/store/slave/checkpoint
 #abort存储路径
 abortFile=/usr/local/rocketmq/store/slave/abort
 #broker角色
 #ASYNC_MASTER 异步复制Master
 #SYNC_MASTER 同步复制Master
 #SLAVE
 brokerRole=SLAVE
 #刷盘方式
 #ASYNC_FLUSH 异步刷盘
 #SYNC_FLUSH 同步刷盘
 flushDiskType=ASYNC_FLUSH

服务启动

  • 启动NameSrv集群(分别在两台服务器启动NameSrv)
cd /usr/local/rocketmq/rocketmq-all-4.7.1-bin-release/bin
 nohup sh mqnamesrv &
  • 启动Broker集群
  • 在IP1上启动master1和Slave2
#master1
 cd /usr/local/rocketmq/rocketmq-all-4.7.1-bin-release/bin
 nohup sh mqbroker -c /usr/local/rocketmq/rocketmq-all-4.7.1-bin-release/conf/2m-2s-sync/broker-a.properties &
 #slave2
 cd /usr/local/rocketmq/rocketmq-all-4.7.1-bin-release/bin
 nohup sh mqbroker -c /usr/local/rocketmq/rocketmq-all-4.7.1-bin-release/conf/2m-2s-sync/broker-b-s.properties &• 在IP2上启动master2和slave1
#master2
 cd /usr/local/rocketmq/rocketmq-all-4.7.1-bin-release/bin
 nohup sh mqbroker -c /usr/local/rocketmq/rocketmq-all-4.7.1-bin-release/conf/2m-2s-sync/broker-b.properties &
 #slave1
 cd /usr/local/rocketMQ/rocketmq-all-4.7.1-bin-release/bin
 nohup sh mqbroker -c /usr/local/rocketmq/rocketmq-all-4.7.1-bin-release/conf/2m-2s-sync/broker-a-s.properties &

集群监控平台搭建 rocketmq_console

  • 工具地址:https://github.com/apache/rocketmq-externals
  • 修改配置

rocketmq.config.namesrvAddr=IP1:9876;IP2:9876

  • 启动监控工具

java -jar rocketmq.jar

  • 启动成功后,就可以通过浏览器http://localhost:8088/可视化的监控到MQ集群的状态

RocketMQ JAVA消息发送示例

1、导入MQ客户端依赖

rocketmq window broker启动闪退 no resource file with name store found_队列_10


2、消息生产者步骤分析

1、创建消息生产者Producer,并制定生产者组名
2、制定NameSrv地址
3、启动Producer
4、创建消息对象,制定Topic、Tag和消息体
5、发送消息
6、关闭生产者Producer

3、消息消费者步骤分析

1、创建消息消费者Consumer,并制定消费者组名
2、制定NameSrv地址
3、订阅Topic、Tag
5、设置回调函数、处理消息
6、启动消费者Codumer

生产者(发送同步消息)代码示例

private void sendSynInfo() {
 //1、创建消息生产者Producer,并制定生产者组名
 DefaultMQProducer producer = new DefaultMQProducer(“group1”);
 //2、制定NameSrv地址
 producer.setNamesrvAddr(“172.23.22.191:9876;172.23.23.249:9876”);
 try {
 //3、启动Producer
 producer.start();
 //4、创建消息对象,制定Topic、Tag和消息体
 for (int i = 0; i < 10; i++) {
 Message msg = new Message(“demo_topic”, (“这是一条同步RocketMQ的消息” + i).getBytes());
 //5、发送消息
 SendResult result = producer.send(msg);
 System.out.println(result);
 Thread.sleep(1000);
 }
 //6、关闭生产者Producer
 producer.shutdown();
 } catch (Exception e) {}
}生产者(发送异步消息)代码示例
private void sendAsynInfo() {
 //1、创建消息生产者Producer,并制定生产者组名
 DefaultMQProducer producer = new DefaultMQProducer(“group1”);
 //2、制定NameSrv地址
 producer.setNamesrvAddr(“172.23.22.191:9876;172.23.23.249:9876”);
 try {
 //3、启动Producer
 producer.start();
 //4、创建消息对象,制定Topic、Tag和消息体
 for (int i = 0; i < 10; i++) {
 Message msg = new Message(“demo_asyn_topic”, (“这是一条异步RocketMQ的消息” + i).getBytes());
 //5、发送消息
 producer.send(msg, new SendCallback() {
 /*发送成功/
 @Override
 public void onSuccess(SendResult sendResult) {
 System.out.println(“成功:” + sendResult);
 }
 /*发送失败/
 @Override
 public void onException(Throwable throwable) {
 System.out.println(“异常:” + throwable);
 }
 });
 Thread.sleep(1000);
 }
 //6、关闭生产者Producer
 producer.shutdown();
 } catch (Exception e) {
 }
 }
 消费者代码示例
 public String consume() {
 //1、创建消息消费者Consumer,并制定消费者组名
 DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(“group2”);
 //2、制定NameSrv地址
 consumer.setNamesrvAddr(“172.23.22.191:9876;172.23.23.249:9876”);
 //3、订阅Topic、Tag
 try {
 consumer.subscribe(“demo_asyn_topic”, (String) null);
 //4、设置回调函数、处理消息
 consumer.registerMessageListener(new MessageListenerConcurrently() {
 @Override
 public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
 for (MessageExt messageExt : msgs) {
 System.out.println(new String(messageExt.getBody()));
 }
 return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
 }
 });
 //5、启动消费者Codumer
 consumer.start();
 } catch (Exception e) {
 }
 return “短信消费成功”;
 }