RocketMQ基础

RocketMQ是什么

  1. MQ(MessageQueue)消息队列是一种“先进先出”的数据结构;
    在这里插入图片描述
  2. RocketMQ是分布式消息中间件

RocketMQ的作用、优缺点

  1. 应用解耦
    系统的耦合性越高,容错性就越低。以电商应用为例,如果耦合调用库存系统、物流系统、支付系统,任何一个子系统除了故障或者因为升级等原因暂时不可用,都会造成下单操作异常,影响用户使用。
    未使用MQ系统结构
    使用消息队列解耦合,系统的耦合就会降低。比如物流系统发生故障,需要几分钟才能修复,在这段时间内,物流系统要处理的数据会暂存在消息队列中,用户的下单操作正常完成。当物流系统恢复后,处理存在消息队列的订单消息即可,用户是感知不到物流系统发生过故障。
    使用MQ系统结构

  2. 流量削峰
    应用系统如果遇到系统请求流量的瞬间猛增,有可能会将系统直接压垮。消息队列可以讲大量请求缓存起来,分散处理,能大大的提高系统的可用性。一般情况下,为了保证系统的稳定性,如果系统负载超过阈值,就会阻止用户请求,比如请求等待等会影响用户体验,而如果使用消息队列将请求缓存起来,等系统处理完毕后通知用户下单完毕,这样好过不能下单。
    从经济方面考虑,业务系统正常时段的QPS如果是1000,流量高峰期是10000,短时的高QPS显然不适合使用高配置高性能的服务器,此时使用MQ进行流量削峰更合算
    在这里插入图片描述
    3.数据分发
    在这里插入图片描述

    通过消息队列可以让数据在多个系统之间进行流通。数据的生产方不需要关心谁来使用数据,只需要将数据发送到MQ,数据使用方直接订阅MQ消费消息即可
    在这里插入图片描述

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

RocketMQ安装、测试

快速入门

  • 1、下载地址
    https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.7.1/rocketmq-all-4.7.1-bin-release.zip
  • 2、环境要求
    Linux服务器、JDK1.8

安装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

在这里插入图片描述

  • 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结构示意图

在这里插入图片描述

  • 集群工作流程:
    • 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双主双从集群工作流程
    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建立长连接发送消息。

服务器环境
在这里插入图片描述
创建消息存储路径
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/index

master1配置-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_FLUSH

slave2配置-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_FLUSH

master2配置-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客户端依赖
在这里插入图片描述
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 “短信消费成功”;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值