二进制版本rocketmq-all-4.5.2-bin-release下载地址 https://download.csdn.net/download/youngwxy/11644587
编译好的rocketmq-console-ng-1.0.0.jar下载地址 https://download.csdn.net/download/youngwxy/11644599
idea java demo下载地址 https://download.csdn.net/download/youngwxy/11644782
目录
1. RocketMQ简介 1
1.1. 官方简介: l
1.2. 核心概念 2
1.3. 同步、异步刷盘 3
1.4. 同步、异步复制 4
1.5. 结构体系 5
1.5.1. NameServer集群 5
1.5.2. Broker集群 5
1.6. 消费模式 6
1.6.1. 集群消费 6
1.6.2. 广播消费 8
1.6.3. 集群消费模拟广播消费 9
2. 搭建RocketMQ环境 9
2.1. 设置ip地址和主机名 9
2.2. 关闭selinux(所有节点机器上都要操作) 10
2.3. 关闭防火墙(所有节点机器上都要操作) 10
2.4. 安装JDK 10
2.5. 拷贝文件、配置环境变量 12
3. 部署RocketMQ 12
3.1. Broker模式 12
3.2. 修改启动脚本 14
3.3. 单机部署 14
3.3.1. 启动nameserver 14
3.3.2. 启动broker 15
3.4. 双服务器集群部署(双主双从异步复制2m-2s-async) 16
3.4.1. 创建存储路径 16
3.4.2. 修改配置文件 16
3.4.3. 修改日志配置文件(两台一样) 23
3.4.4. 启动服务 23
4. 使用自带模拟测试 25
5. 编写java程序测试 26
5.1. 创建Spring boot项目 26
5.2. 添加依赖 27
5.3. 编写资源文件 28
5.4. 编写代码 28
6. 部署rocketmq-console 33
7. 服务关闭 34
8. 补充 35
8.1. 特性 35
8.2. 线上建议关闭autoCreateTopicEnable配置 35
8.3. broker master宕机情况是否会丢消息 35
1.RocketMQ简介
RocketMQ是基于发布/订阅模式的。
RocketMQ中的四个角色:Producer(消息生产者)、Consumer(消息消费者)、Broker(消息暂存者)、NameServer(消息协调者)
1.1官方简介:
l RocketMQ是一款分布式、队列模型的消息中间件,具有以下特点:
l 能够保证严格的消息顺序
l 提供丰富的消息拉取模式
l 高效的订阅者水平扩展能力
l 实时的消息订阅机制
l 亿级消息堆积能力
1.2 核心概念
生产者(Producer):消息发送方,将业务系统中产生的消息发送到brokers(brokers可以理解为消息代理,生产者和消费者之间是通过brokers进行消息的通信),rocketmq提供了以下消息发送方式:同步、异步、单向。
生产者组(Producer Group):相同角色的生产者被归为同一组,比如通常情况下一个服务会部署多个实例,这多个实例就是一个组,生产者分组的作用只体现在消息回查的时候,即如果一个生产者组中的一个生产者实例发送一个事务消息到broker后挂掉了,那么broker会回查此实例所在组的其他实例,从而进行消息的提交或回滚操作。
消费者(Consumer):消息消费方,从brokers拉取消息。站在用户的角度,有以下两种消费者。
主动消费者(PullConsumer):从brokers拉取消息并消费。
被动消费者(PushConsumer):内部也是通过pull方式获取消息,只是进行了扩展和封装,并给用户预留了一个回调接口去实现,当消息到底的时候会执行用户自定义的回调接口。
消费者组(Consumer Group):和生产者组类似。其作用体现在实现消费者的负载均衡和容错,有了消费者组变得异常容易。需要注意的是:同一个消费者组的每个消费者实例订阅的主题必须相同。
主题(Topic):主题就是消息传递的类型。一个生产者实例可以发送消息到多个主题,多个生产者实例也可以发送消息到同一个主题。同样的,对于消费者端来说,一个消费者组可以订阅多个主题的消息,一个主题的消息也可以被多个消费者组订阅。
消息(Message):消息就像是你传递信息的信封。每个消息必须指定一个主题,就好比每个信封上都必须写明收件人。
消息队列(Message Queues):在主题内部,逻辑划分了多个子主题,每个子主题被称为消息队列。这个概念在实现最大并发数、故障切换等功能上有巨大的作用。
标签(Tag):标签,可以被认为是子主题。通常用于区分同一个主题下的不同作用或者说不同业务的消息。同时也是避免主题定义过多引起性能问题,通常情况下一个生产者组只向一个主题发送消息,其中不同业务的消息通过标签或者说子主题来区分。
消息代理(Broker):消息代理是RockerMQ中很重要的角色。它接收生产者发送的消息,进行消息存储,为消费者拉取消息服务。它还存储消息消耗相关的元数据,包括消费群体,消费进度偏移和主题/队列信息。
命名服务(Name Server):命名服务作为路由信息提供程序。生产者/消费者进行主题查找、消息代理查找、读取/写入消息都需要通过命名服务获取路由信息。
消息顺序(Message Order):当我们使用DefaultMQPushConsumer时,我们可以选择使用“orderly”还是“concurrently”。
orderly:消费消息的有序化意味着消息被生产者按照每个消息队列发送的顺序消费。如果您正在处理全局顺序为强制的场景,请确保您使用的主题只有一个消息队列。注意:如果指定了消费顺序,则消息消费的最大并发性是消费组订阅的消息队列数。
concurrently:当同时消费时,消息消费的最大并发仅限于为每个消费客户端指定的线程池。注意:此模式不再保证消息顺序。
1.3 同步、异步刷盘
RocketMQ的消息是存储到磁盘上的,这样既能保证断电后恢复,又可以让存储的消息量超出内存的限制。
RocketMQ为了提高性能,会尽可能地保证磁盘的顺序写。消息在通过Producer写入RocketMQ的时候,有两种写磁盘方式:
1)异步刷盘方式:在返回写成功状态时,消息可能只是被写入了内存的PAGECACHE,写操作的返回快,吞吐量大;当内存里的消息量积累到一定程度时,统一触发写磁盘操作,快速写入
2)同步刷盘方式:在返回写成功状态时,消息已经被写入磁盘。具体流程是,消息写入内存的PAGECACHE后,立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态。
同步刷盘还是异步刷盘,是通过Broker配置文件里的flushDiskType参数设置的,这个参数可以设置成SYNC_FLUSH(同步刷盘)、ASYNC_FLUSH(异步刷盘)
实际应用中要结合业务场景,合理设置刷盘方式, SYNC_FLUSH方式由于频繁的触发写磁盘动作,会明显降低性能。通常情况下,应该把Master和Slave设置成ASYNC_FLUSH的刷盘方式。
1.4 同步、异步复制
如果一个broker组有Master和Slave,消息需要从Master复制到Slave上,有同步和异步两种复制方式。
同步复制是等Master和Slave均写成功后才反馈给客户端写成功状态;异步复制方式是只要Master写成功即可反馈给客户端写成功状态
这两种复制方式各有优劣,在异步复制方式下,系统拥有较低的延迟和较高的吞吐量,但是如果Master出了故障,有些数据因为没有被写入Slave,有可能会丢失;在同步复制方式下,如果Master出故障,Slave上有全部的备份数据,容易恢复,但是同步复制会增大数据写入延迟,降低系统吞吐量。
同步复制和异步复制是通过Broker配置文件里的brokerRole参数进行设置的,这个参数可以被设置成ASYNC_MASTER(主从异步复制)、SYNC_MASTER(主从同步复制)、SLAVE三个值中的一个。
实际应用中要结合业务场景,合理设置主从复制方式,通常情况下,主从之间配置成SYNC_MASTER的复制方式,这样即使有一台机器出故障,仍然可以保证数据不丢。
1.5 结构体系
如图所示为RocketMQ基本的部署结构,主要分为NameServer集群、Broker集群、Producer集群和Consumer集群四个部分。
1.5.1 NameServer集群
NameServer的作用是注册中心,类似于Zookeeper,但又有区别于它的地方。每个NameServer节点互相之间是独立的,没有任何信息交互,也就不存在任何的选主或者主从切换之类的问题,因此NameServer与Zookeeper相比更轻量级。单个NameServer节点中存储了活跃的Broker列表(包括master和slave),这里活跃的定义是与NameServer保持有心跳。
1.5.2 Broker集群
Broker是具体提供业务的服务器,单个Broker节点与所有的NameServer节点保持长连接及心跳,并会定时将Topic信息注册到NameServe。
Broker中分master和slave两种角色,每个master可以对应多个slave,但一个slave只能对应一个master,master和slave通过指定相同的Brokername,不同的BrokerId (master为0)成为一个组。master和slave之间的同步方式分为同步双写和异步复制,异步复制方式master和slave之间虽然会存在少量的延迟,但性能较同步双写方式要高出10%左右。
另外,Broker中还存在一些非常重要的名词需要说明:
1.5.2.1 Topic和Queue
RocketMQ的Topic/Queue和JMS中的Topic/Queue概念有一定的差异,JMS中所有消费者都会消费一个Topic消息的副本,而Queue中消息只会被一个消费者消费;但到了RocketMQ中Topic只代表普通的消息队列,而Queue是组成Topic的更小单元,集群消费模式下一个消费者只消费该Topic中部分Queue中的消息,当一个消费者开启广播模式时则会消费该Topic下所有Queue中的消息。Topic和Queue的具体关系可以参考下图
1.6 消费模式
1.6.1 集群消费
当 consumer 使用集群消费时,每条消息只会被 consumer 集群内的任意一个 consumer 实例消费一次。举个例子,当一个 consumer 集群内有 3 个consumer 实例(假设为consumer 1、consumer 2、consumer 3)时,一条消息投递过来,只会被consumer 1、consumer 2、consumer 3中的一个消费。
同时记住一点,使用集群消费的时候,consumer 的消费进度是存储在 broker 上,consumer 自身是不存储消费进度的。消息进度存储在 broker 上的好处在于,当你 consumer 集群是扩大或者缩小时,由于消费进度统一在broker上,消息重复的概率会被大大降低了。
注意:在集群消费模式下,并不能保证每一次消息失败重投都投递到同一个 consumer 实例。
1.6.1.1测试
三个Consumer加入同一组PushConsumer
Producer发送10条数据
Consumer1
Consumer2
Consumer3
1.6.2 广播消费
当 consumer 使用广播消费时,每条消息都会被 consumer 集群内所有的 consumer 实例消费一次,也就是说每条消息至少被每一个 consumer 实例消费一次。举个例子,当一个 consumer 集群内有 3 个 consumer 实例(假设为 consumer 1、consumer 2、consumer 3)时,一条消息投递过来,会被 consumer 1、consumer 2、consumer 3都消费一次。
与集群消费不同的是,consumer 的消费进度是存储在各个 consumer 实例上,这就容易造成消息重复。还有很重要的一点,对于广播消费来说,是不会进行消费失败重投的,所以在 consumer 端消费逻辑处理时,需要额外关注消费失败的情况。
虽然广播消费能保证集群内每个 consumer 实例都能消费消息,但是消费进度的维护、不具备消息重投的机制大大影响了实际的使用。因此,在实际使用中,更推荐使用集群消费,因为集群消费不仅拥有消费进度存储的可靠性,还具有消息重投的机制。而且,我们通过集群消费也可以达到广播消费的效果。
1.6.3 集群消费模拟广播消费
如果业务上确实需要使用广播消费,那么我们可以通过创建多个 consumer 实例,每个 consumer 实例属于不同的 consumer group,但是它们都订阅同一个 topic。举个例子,我们创建 3 个 consumer 实例,consumer 1(属于consumer group 1)、consumer 2(属于 consumer group 2)、consumer 3(属于consumer group 3),它们都订阅了 topic A ,那么当 producer 发送一条消息到 topic A 上时,由于 3 个consumer 属于不同的 consumer group,所以 3 个consumer都能收到消息,也就达到了广播消费的效果了。 除此之外,每个 consumer 实例的消费逻辑可以一样也可以不一样,每个consumer group还可以根据需要增加 consumer 实例,比起广播消费来说更加灵活。
2 搭建RocketMQ环境
2.1 设置ip地址和主机名
若集群部署,则在hosts文件中要加入集群每一台服务器
192.168.1.211 node211.nugget.com node211
192.168.1.212 node212.nugget.com node212
2.2 关闭selinux(所有节点机器上都要操作)
首先查看 SELinux功能是否开启
getenforce
如果显示Permissive 或者 Disabled 该步骤直接跳过,如果是enforcing ,进行下一步
vi /etc/selinux/config 或者 vi /etc/sysconfig/selinux
设置 SELINUX=enforcing 为 SELINUX=permissive(/disabled)
setenforce 0 # 让设置生效
getenforce 查看
2.3 关闭防火墙(所有节点机器上都要操作)
vi /etc/selinux/config
将SELINUX=enforcing改为SELINUX=disabled
查看防火墙状态
firewall-cmd --state
停止firewall
systemctl stop firewalld.service
禁止firewall开机启动
systemctl disable firewalld.service
2.4 安装JDK
2.5 拷贝文件、配置环境变量
下载地址 https://download.csdn.net/download/youngwxy/11644587
拷贝二进制版本rocketmq-all-4.5.2-bin-release到/opt/module
配置环境变量 vi /etc/profile
在尾部追加
export ROCKETMQ_HOME=/opt/module/rocketmq-all-4.5.2-bin-release
export PATH=$ROCKETMQ_HOME/bin:$PATH
export NAMESRV_ADDR=192.168.1.114:9876
最后输入以下命令source /etc/profile,使配置生效,RocketMQ的安装及环境变量配置就完成了
3 部署RocketMQ
3.1 Broker模式
Broker节点的配置文件在/rocketmq/conf下面,有三种配置方式
2m-noslave: 多Master模式
2m-2s-sync: 多Master多Slave模式,同步双写
2m-2s-async:多Master多Slave模式,异步复制
不同的模式有相对应的配置方法,部署多少集群,就要相应创建多少个配置文件,我们拿多Master模式举例,进去会发现里面有两个文件:
代表两个Master,查看原始文件的内容:
里面有若干参数配置,其余均为默认配置,如果需要集群配置,需根据实际情况设置相应参数,官网给出了Broker配置的参数列表:
文档地址是http://rocketmq.apache.org/docs/rmq-deployment/
特别强调的是:如果nameserver要集群的话,要在namesrvAddr上列出所有nameserver节点的IP和端口;brokerRole要填写当前节点的角色有ASYNC_MASTER、SYNC_MASTER、SLAVE三种。
3.2 修改启动脚本
服务启动脚本在/opt/module/rocketmq-all-4.5.2-bin-release/bin/目录下
根据需求修改默认内存参数
cd /opt/module/rocketmq-all-4.5.2-bin-release/bin/
调一下JVM,包括nameserver 和 broker。因为默认的值适合在生产上使用,限于自己机器的配置,参数调小一下。
1.vi runbroker.sh -server -Xms512m -Xmx512m -Xmn256m
2. vi runserver.sh -server -Xms512m -Xmx512m -Xmn128m -XX:PermSize=128m -XX:MaxPermSize=320m
3. vi tools.sh -server -Xms256m -Xmx256m -Xmn128m -XX:PermSize=128m -XX:MaxPermSize=128m
3.3 单机部署
3.3.1 启动nameserver
在/opt/module/rocketmq-all-4.5.2-bin-release路径下执行命令nohup sh mqnamesrv &
在启动状态执行查询命令tail -f ~/logs/rocketmqlogs/namesrv.log
从中可以看出nameserver启动成功。
3.3.2 启动broker
3.3.2.1 默认启动
在/opt/module/rocketmq-all-4.5.2-bin-release路径下执行命令
nohup sh mqbroker -n 192.168.1.114:9876 &
3.3.2.2 自定义启动
在conf下创建 1m-noslave 目录
创建broker-1master.properties文件并写入
brokerClusterName=NuggetCluster
brokerName=broker-master-nugget
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
执行
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/1m-noslave/broker-1master.properties -n 192.168.1.114:9876 &
执行命令tail -f ~/logs/rocketmqlogs/broker.log查看broker的启动状态:
说明我们启动broker成功,broker在nameserver上也注册成功。
3.4 两台服务器集群部署(双主双从异步复制2m-2s-async)
3.4.1 创建存储路径
cd /opt/module/rocketmq-all-4.5.2-bin-release
mkdir -p data/rocketmq/store/{rootdir-a-m,commitlog-a-m,rootdir-b-s,commitlog-b-s}
mkdir -p data/rocketmq/store/{rootdir-b-m,commitlog-b-m,rootdir-a-s,commitlog-a-s}
3.4.2 修改配置文件
cd /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async
3.4.2.1 192.168.1.211 角色为:broker-a-master & broker-b-slave
vi broker-a.properties
# 是否允许 Broker 自动创建Topic
autoCreateTopicEnable=true
# 是否允许 Broker 自动创建订阅组
autoCreateSubscriptionGroup=true
#所属集群名字
brokerClusterName=NuggetRocketMQ
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=node211.nugger.com
#brokerId 0 表示 Master,>0 表示 Slave
brokerId=0
#Broker role有3种:SYNC MASTER、ASYNC MASTER、SLAVE。关键词SYNC和ASYNC表示Master和Slave之间同步消息的机制,SYNC即同步更新,
#指当Slave和Master消息同步完成后,再返回发送成功的状态。ASYNC即异步更新,master与slave有短暂消息延迟,毫秒级。本次搭建使用
#了异步复制集群模式,线上环境推荐使用同步双写模式,即SYNC_MASTER
brokerRole=ASYNC_MASTER
# 刷盘方式 ASYNC_FLUSH 异步刷盘
flushDiskType=ASYNC_FLUSH
##Broker 对外服务的监听端口
listenPort=10911
#nameserver地址,分号分割
namesrvAddr=192.168.1.211:9876; 192.168.1.212:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
brokerIP1=192.168.1.211
#存储路径
storePathRootDir=/opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/rootdir-a-m
storePathCommitLog=/opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/commitlog-a-m
# 消费队列存储路径存储路径
#storePathConsumerQueue=/opt/rocketmq-4.3.0/data/store/consumequeue
#消息索引存储路径
#storePathIndex=/opt/rocketmq-4.3.0/data/store/index
#checkpoint 文件存储路径
#storeCheckpoint=/opt/rocketmq-4.3.0/data/store/checkpoint
#abort 文件存储路径
#abortFile=/opt/rocketmq-4.3.0/data/store/abort
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
# commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
vim broker-b-s.properties
brokerClusterName=NuggetRocketMQ
brokerName=node212.nugger.com
brokerId=1
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
listenPort=10921
#nameserver地址,分号分割
namesrvAddr=192.168.1.211:9876; 192.168.1.212:9876
brokerIP1=192.168.1.211
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#存储路径
storePathRootDir=/opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/rootdir-a-m
storePathCommitLog=/opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/commitlog-a-m
# 消费队列存储路径存储路径
#storePathConsumerQueue=/opt/rocketmq-4.3.0/data2/store/consumequeue2
#消息索引存储路径
#storePathIndex=/opt/rocketmq-4.3.0/data2/store/index2
#checkpoint 文件存储路径
#storeCheckpoint=/opt/rocketmq-4.3.0/data2/store/checkpoint2
#abort 文件存储路径
#abortFile=/opt/rocketmq-4.3.0/data2/store/abort2
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
# commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
#diskMaxUsedSpaceRatio=88
3.4.2.2 192.168.1.212 角色:broker-b-master & broker-a-slave
vi broker-b.properties
brokerClusterName=NuggetRocketMQ
brokerName=node212.nugger.com
brokerId=0
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
listenPort=10911
#nameserver地址,分号分割
namesrvAddr=192.168.1.211:9876; 192.168.1.212:9876
brokerIP1=192.168.1.212
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
storePathRootDir=/opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/rootdir-b-m
storePathCommitLog=/opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/commitlog-b-m
# 消费队列存储路径存储路径
#storePathConsumerQueue=/opt/rocketmq-4.3.0/data/store/consumequeue
#消息索引存储路径
#storePathIndex=/opt/rocketmq-4.3.0/data/store/index
#checkpoint 文件存储路径
#storeCheckpoint=/opt/rocketmq-4.3.0/data/store/checkpoint
#abort 文件存储路径
#abortFile=/opt/rocketmq-4.3.0/data/store/abort
#限制的消息大小
maxMessageSize=65536
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
# commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
#diskMaxUsedSpaceRatio=88
vim broker-a-s.properties
brokerClusterName=NuggetRocketMQ
brokerName=node211.nugger.com
brokerId=1
listenPort=10921
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.1.211:9876; 192.168.1.212:9876
brokerIP1=192.168.1.212
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
storePathRootDir=/opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/rootdir-a-s
storePathCommitLog=/opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/commitlog-a-s
# 消费队列存储路径存储路径
#storePathConsumerQueue=/opt/rocketmq-4.3.0/data2/store/consumequeue
#消息索引存储路径
#storePathIndex=/opt/rocketmq-4.3.0/data2/store/index
#checkpoint 文件存储路径
#storeCheckpoint=/opt/rocketmq-4.3.0/data2/store/checkpoint
#abort 文件存储路径
#abortFile=/opt/rocketmq-4.3.0/data2/store/abort
#限制的消息大小
maxMessageSize=65536
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
# commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
#diskMaxUsedSpaceRatio=88
3.4.3 修改日志配置文件(两台一样)
mkdir -p /opt/module/rocketmq-all-4.5.2-bin-release/logs
cd /opt/module/rocketmq-all-4.5.2-bin-release/conf
sed -i 's#${user.home}#/opt/module/rocketmq-all-4.5.2-bin-release#g' *.xml
3.4.4 启动服务
RocketMQ服务需要先启动NameService,再启动BrokerMaster,最后启动BrokerSlave
3.4.4.1 启动顺序
211 212 上都 启动nameServer
source /etc/profile
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqnamesrv > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/mqnamesrv.log 2>&1
211上启动master
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async/broker-a.properties > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/broker-a-m.log 2>&1 &
212上启动master
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async/broker-b.properties > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/broker-b-m.log 2>&1 &
211上启动slave
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async/broker-b-s.properties > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/broker-b-s.log 2>&1 &
212上启动slave
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async/broker-a-s.properties > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/broker-a-s.log 2>&1 &
3.4.4.2 编写脚本启动
为了未来方便运维,最好是写好相应的服务启动脚本
1、编写启动nameserver脚本
mkdir -p /opt/scripts/rocketmq
cd /opt/scripts/rocketmq
vi start_rocketmq_nameserver.sh
#!/bin/bash
source /etc/profile
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqnamesrv > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/mqnamesrv.log 2>&1 &
2、编写启动broker脚本
192.168.1.211 node211.nugget.com
vi start_broker_a_master.sh
#!/bin/bash
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async/broker-a.properties > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/broker-a-m.log 2>&1 &
vi start_broker_b_slave.sh
#!/bin/bash
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async/broker-b-s.properties > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/broker-b-s.log 2>&1 &
192.168.1.212 node212.nugget.com
vi start_broker_b_master.sh
#!/bin/bash
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async/broker-b.properties > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/broker-b-m.log 2>&1 &
vi start_broker_a_slave.sh
#!/bin/bash
nohup sh /opt/module/rocketmq-all-4.5.2-bin-release/bin/mqbroker -c /opt/module/rocketmq-all-4.5.2-bin-release/conf/2m-2s-async/broker-a-s.properties > /opt/module/rocketmq-all-4.5.2-bin-release/data/rocketmq/store/broker-a-s.log 2>&1 &
4 使用自带模拟测试
cd /opt/module/rocketmq-all-4.5.2-bin-release/bin
执行
sh tools.sh org.apache.rocketmq.example.quickstart.Producer
模拟Producer发消息,如图则发送成功
再执行
sh tools.sh org.apache.rocketmq.example.quickstart.Consumer
模拟Consumer收消息
会出现很多条数据,说明接收成功
也可以打开两个终端;先在一个终端启动Consumer接收,然后另外一个启动Producer发送,此时切换回接收终端可以看到接收到的数据
5 编写java程序测试
demo下载地址 https://download.csdn.net/download/youngwxy/11644782
5.1 创建Spring boot项目
5.2 添加依赖
在pom.xml中添加
<!-- RocketMq客户端相关依赖 -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.1.0-incubating</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-common</artifactId>
<version>4.1.0-incubating</version>
</dependency>
右下角出现弹窗,选择enabled auto..
5.3 编写资源文件
resources文件中properties中写入
# 消费者的组名
apache.rocketmq.consumer.PushConsumer=PushConsumer
# 生产者的组名
apache.rocketmq.producer.producerGroup=Producer
# NameServer地址
apache.rocketmq.namesrvAddr=192.168.1.114:9876
5.4 编写代码
在包中创建Producer和Consumer文件
Producer.java
@Component
public class Producer {
/**
* 生产者的组名
*/
@Value("${apache.rocketmq.producer.producerGroup}")
private String producerGroup;
/**
* NameServer 地址
*/
@Value("${apache.rocketmq.namesrvAddr}")
private String namesrvAddr;
@PostConstruct
public void defaultMQProducer() {
//生产者的组名
DefaultMQProducer producer = new DefaultMQProducer(producerGroup);
//指定NameServer地址,多个地址以 ; 隔开
producer.setNamesrvAddr(namesrvAddr);
try {
/**
* Producer对象在使用之前必须要调用start初始化,初始化一次即可
* 注意:切记不可以在每次发送消息时,都调用start方法
*/
producer.start();
for (int i = 0; i < 100; i++) {
String messageBody = "我是消息内容:" + i;
String message = new String(messageBody.getBytes(), "utf-8");
//构建消息
Message msg = new Message("PushTopic" /* PushTopic */, "push"/* Tag */, "key_" + i /* Keys */, message.getBytes());
//发送消息
SendResult result = producer.send(msg);
System.out.println("发送响应:MsgId:" + result.getMsgId() + ",发送状态:" + result.getSendStatus());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
producer.shutdown();
}
}
}
鼠标点击红色标识符,按下alt+enter引入包
Consumer.java
@Component
public class Consumer {
/**
* 消费者的组名
*/
@Value("${apache.rocketmq.consumer.PushConsumer}")
private String consumerGroup;
/**
* NameServer地址
*/
@Value("${apache.rocketmq.namesrvAddr}")
private String namesrvAddr;
@PostConstruct
public void defaultMQPushConsumer() {
//消费者的组名
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(consumerGroup);
//指定NameServer地址,多个地址以 ; 隔开
consumer.setNamesrvAddr(namesrvAddr);
try {
//订阅PushTopic下Tag为push的消息
consumer.subscribe("PushTopic", "push");
//设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费
//如果非第一次启动,那么按照上次消费的位置继续消费
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
//可以修改每次消费消息的数量,默认设置是每次消费一条
consumer.setConsumeMessageBatchMaxSize(1);
//设置消费模式为广播
consumer.setMessageModel(MessageModel.BROADCASTING);
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext context) {
try {
for (MessageExt messageExt : list) {
System.out.println("messageExt: " + messageExt);//输出消息内容
String messageBody = new String(messageExt.getBody(), "utf-8");
System.out.println("消费响应:Msg: " + messageExt.getMsgId() + ",msgBody: " + messageBody);//输出消息内容
}
} catch (Exception e) {
e.printStackTrace();
return ConsumeConcurrentlyStatus.RECONSUME_LATER; //稍后再试
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; //消费成功
}
});
consumer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里需要注意,默认情况下,一台服务器只能启动一个Producer或Consumer实例,所以如果需要在一台服务器启动多个实例,需要设置实例的名称,如要再建一个producer:
producer.setNamesrvAddr(“121.42.179.195:9876”);
producer.setInstanceName(“Producer2”);
6 部署rocketmq-console
下载地址 https://download.csdn.net/download/youngwxy/11644599
mkdir -p /opt/module/rocketmq-console/
把下载好的rocketmq-console-ng-1.0.0.ja放在这里
集群部署要把各服务器地址都列出来,如下
java -jar rocketmq-console-ng-1.0.0.jar --server.port=8080 --rocketmq.config.namesrvAddr=192.168.1.211:9876;192.168.1.212:9876 &
单机部署启动管控台如下
java -jar rocketmq-console-ng-1.0.0.jar --server.port=8080 --rocketmq.config.namesrvAddr=192.168.1.114:9876 &
7 服务关闭
一般先关闭所有borker后再关闭namesever
cd /opt/module/rocketmq-all-4.5.2-bin-release/bin/
chmod 777 mqshutdown
关闭nameserver:
/opt/module/rocketmq-all-4.5.2-bin-release/bin/mqshutdown namesrv
关闭broker:
/opt/module/rocketmq-all-4.5.2-bin-release/bin/mqshutdown broker
8 补充
8.1 特性
Broker 重启对客户端的影响
Broker 重启可能会导致正在发往这台机器的的消息发送失败,RocketMQ提供了一种优雅关闭Broker的方法,通过执行以下命令会清除Broker的写权限,过40s后,所有客户端都会更新Broker路由信息,此时再关闭Broker就不会发生发送消息失败的情况,因为所有消息都发往了其他 Broker。
# sh mqadmin wipeWritePerm -b brokerName -n namesrvAddr
Master 与Slave的关系
RocketMQ的开源版本,Master宕机,Slave不能切换为Master,这里的Slave不可写,但可读,类似于 Mysql 主备方式。
8.2 线上建议关闭autoCreateTopicEnable配置
该配置用于在Topic不存在时自动创建,会造成的问题是自动新建的Topic只会存在于一台broker上,后续所有对该Topic的请求都会局限在单台broker上,造成单点压力。
8.3 broker master宕机情况是否会丢消息
broker master宕机,虽然理论上来说不能向该broker写入但slave仍然能支持消费,但受限于rocketmq的网络连接机制,默认情况下最多需要30秒,消费者才会发现该情况,这个时间可通过修改参数pollNameServerInteval来缩短。这个时间段内,发往该broker的请求都是失败的,而且该broker的消息无法消费,因为此时消费者不知道该broker已经挂掉。 直到消费者得到master宕机通知后,才会转向slave进行消费,但是slave不能保证master的消息100%都同步过来了,因此会有少量的消息丢失。但是消息最终不会丢,一旦master恢复,未同步过去的消息仍然会被消费掉