中间件-rocketmq
Rocketmq由四部分组成
producer 消息的生产者
Consumer 消息的消费者
Broker 消息的储存者(节点)
NameServer 注册中心,NameServer维护了一份Broker的地址列表和,broker在启动的时候会去
单个broker和所有nameServer保持长连接
一个topic分布在多个broker上,一个broker可以配置多个topic,它们是多对多的关系。
如果某个topic消息量很大,应该给它多配置几个队列,并且尽量多分布在不同broker上,减轻某个broker的压力。
topic消息量都比较均匀的情况下,如果某个broker上的队列越多,则该broker压力越大。
RocketMQ的启动顺序是先启动NameServer,再启动Broker
安装
jdk安装
下载:http://rocketmq.apache.org/dowloading/releases/
wget http://mirror.bit.edu.cn/apache/rocketmq/4.4.0/rocketmq-all-4.4.0-bin-release.zip
unzip rocketmq-all-4.0.0-incubating-bin-release.zip
mv apache-rocketmq-all /usr/local/rocketmq
mvn -Prelease-all -DskipTests clean install -U #mvn编译
三种模式:
2m-2s-async :2个master,2个slave,async异步复制:性能最好,但是遇到突发情况会有少量数据丢失。
2m-2s-sync :2个master,2个slave,sync同步双写:比异步复制的性能差10%,但能保证数据不丢失
2m-noslave :2个master,没有slave:优点是配置简单、快捷,但是一旦MASTER机器宕机或出现问题就无法提供服务
重点配置说明:
brokerClusterName:同一个集群中,brokerClusterName需一致
brokerId:0 表示 Master,>0 表示 Slave
namesrvAddr:配置多个用分号分隔
brokerIP1:默认系统自动识别,但是某些多网卡机器会存在识别错误的情况,建议都手工指定
brokerRole:选择Broker的角色
flushDiskType:选择刷盘方式
配置:
vim broker-a.properties
#所属集群名字
brokerClusterName=rocketmq-cluster
#broker名字,每队master和slave保持一致
brokerName=broker-a
#0 表示 Master,>0 表示 Slave
brokerId=0
#指定主机ip,默认系统自动识别,但是某些多网卡机器会存在识别错误的情况,建议都手工指定
brokerIP1 = 主机IP
#nameServer地址,分号分割
namesrvAddr=主机IP:9876;主机IP:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=10911
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=120
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/usr/local/rocketmq/store
#commitLog 存储路径
storePathCommitLog=/usr/local/rocketmq/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/usr/local/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/usr/local/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/usr/local/rocketmq/store/checkpoint
#Broker 的角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRole=ASYNC_MASTER
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
#checkTransactionMessageEnable=false
#abort 文件存储路径
abortFile=/usr/javawork/apache-rocketmq/store/abort
#发消息线程池数量
#sendMessageThreadPoolNums=128
#拉消息线程池数量
#pullMessageThreadPoolNums=128
#限制的消息大小
maxMessageSize=65536
#解决报错broker busy或者system busy
sendMessageThreadPoolNums=64
#发送消息是否使用可重入锁(4.1版本以上才有)
useReentrantLockWhenPutMessage=true
pullMessageTreadPoolNums=64
#消息发送队列等待时间,默认200
waitTimeMillsInSendQueue=400
## Linux启用epoll IO 模型
useEpollNativeSelector=tru
#broker根据tag过滤消息,启动1个进程。减少网络流量,但增加CPU负载
filterServerNumbers=1
##缩短注册间隔时间
registerNameServerPeriod=10000
##启用失败broker规避
sendLatencyFaultEnable = true
#磁盘写保护警戒位,超过则禁止写入
DiskSpaceCleanForciblyRatio = 85
#默认值,磁盘利用率,超过则清理因素一为真
DiskSpaceWarningLevelRatio=98
slave配置同master(修改brokerRole和brokerId)
vim broker-a-s.properties
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=1
deleteWhen=04
fileReservedTime=48
#作为broker-a的slave
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
namesrvAddr=172.16.54.128:9876;172.16.54.130:9876
listenPort=20911
#存储路径
storePathRootDir=/usr/local/rocketmq/slave/store
#commitLog 存储路径
storePathCommitLog=/usr/local/rocketmq/slave/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/usr/local/rocketmq/slave/store/consumequeue
#消息索引存储路径
storePathIndex=/usr/local/rocketmq/slave/store/index
#checkpoint 文件存储路径
storeCheckpoint=/usr/local/rocketmq/slave/store/checkpoint
优化:
配置优化
#主从异步复制
brokerRole=ASYNC_MASTER
#异步刷盘
flushDiskType=ASYNC_FLUSH
#线上关闭自动创建topic
autoCreateTopicEnable=false
#发送消息的最大线程数,默认1
sendMessageThreadPoolNums=32
#使用可重入锁
useReentrantLockWhenPutMessage=true
#发送消息线程等待时间,默认200ms
waitTimeMillsInSendQueue=1000
#开启临时存储池
transientStorePoolEnable=true
#开启Slave读权限(分担master 压力)
slaveReadEnable=true
#关闭堆内存数据传输
transferMsgByHeap=false
#开启文件预热
warmMapedFileEnable=true
JVM优化
设置RocketMQ运行的JVM内存(非必须),选用 G1回收器
vim bin/runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
vim bin/runserver.sh
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
###如
-server -Xms8g -Xmx8g -Xmn4g
-XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25
-XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0
-XX:SurvivorRatio=8 -XX:+DisableExplicitGC
-verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails
-XX:+PrintGCDateStamps -XX:+PrintGCApplicationStoppedTime
-XX:+PrintAdaptiveSizePolicy
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m
LINUX优化:
减少使用交换区,提升性能
cat /proc/sys/vm/swappiness
设置 swappiness = 1
vm.extra_free_kbytes,告诉VM在后台回收(kswapd)启动的阈值与直接回收(通过分配进程)的阈值之间保留额外的可用内存。RocketMQ使用此参数来避免内存分配中的长延迟。(与具体内核版本相关)
vm.min_free_kbytes,如果将其设置为低于1024KB,将会巧妙的将系统破坏,并且系统在高负载下容易出现死锁。
vm.max_map_count,限制一个进程可能具有的最大内存映射区域数。RocketMQ将使用mmap加载CommitLog和ConsumeQueue,因此建议将为此参数设置较大的值。(agressiveness --> aggressiveness)
vm.swappiness,定义内核交换内存页面的积极程度。较高的值会增加攻击性,较低的值会减少交换量。建议将值设置为10来避免交换延迟。
File descriptor limits,RocketMQ需要为文件(CommitLog和ConsumeQueue)和网络连接打开文件描述符。我们建议设置文件描述符的值为655350。
Disk scheduler,RocketMQ建议使用I/O截止时间调度器,它试图为请求提供有保证的延迟。
打开NUMA,在GRUB中配置开启NUMA
vi /boot/grub/grub.conf
添加boot参数:numa=on
重启
查看numa node个数
numactl --hardware
如果看到了>1个节点,即为支持NUMA
启动
service firewalld stop #关闭防火墙
启动namesrv
sh bin/mqnamesrv &
启动broker-master
sh mqbroker -c ../conf/2m-2s-async/broker-a.properties &
启动broker-slave
sh mqbroker -c ../conf/2m-2s-async/broker-a-s.properties &
#注意两台主机启动broker时后面的-c记得加载你配置好的配置文件路径,别加载错了
RocketMQ集群平滑下线或重启某个节点
如果直接下线该master,由于主从异步复制,可能导致部分消息来不及复制到slave造成消息丢失。所以该方案不可行。
另一种方案选择:关闭该broker的写入权限,待该broker不再有写入和消费时,再下线该节点。
关闭broker写权限
bin/mqadmin updateBrokerConfig -b 192.168.x.x:10911 -n 192.168.x.x:9876 -k brokerPermission -v 4
观察节点流量
bin/mqadmin clusterList -n 192.168.x.x:9876
观察InTPS和OutTPS,理想情况都为零时,并不再变化时,则该节点可下线了。
然而,在实际过程中并没有出现为零的情况,InTPS和OutTPS总是有值,有时个位数字有时是两位数字,大部分时间在20多的值。此刻要分析下broker目前的消费状态
观察broker消费状态
sh bin/mqadmin brokerConsumeStats -b 192.168.x.x:10911 -n 192.168.x.x:9876 >> brokerConsumeStats.tmp
查看brokerConsumeStats.tmp,主要查看#LastTime和#Diff。发现%RETRY%重试类队列#Diff有很微小(1或者3)的数据,
而其他topic均为0. LastTime时间最新也是发生在%RETRY%队列中。此时可以让该节点下线操作
borker读写权限恢复
bin/mqadmin updateBrokerConfig -b 192.168.x.x:10911 -n 192.168.x.x:9876 -k brokerPermission -v 6
观察各节点流量是否正常
可视化控制台安装
任意一台机器
git clone https://github.com/apache/rocketmq-externals.git
cd rocketmq-externals-master/rocketmq-console
vim src/main/resources/application.properties
添加两个namesvr的主机ip
rocketmq.config.namesrvAddr=172.16.54.128:9876;172.16.54.130:9876
然后进项目根目录,运行项目
mvn clean package -Dmaven.test.skip=true
nohup java -jar rocketmq-console-ng-1.0.0.jar 2>&1 &
web访问
常用操作:
创建topic
sh mqadmin updateTopic -t TopicTest -c DefaultCluster -n 192.168.0.1:9876
-t topic名称
-c 集群创建使用
-n nameServer地址,分号隔开
创建订阅组
sh mqadmin updateSubGroup -c DefaultCluster -g TopicTestGroup -n 192.168.0.1:9876
删除topic
sh mqadmin deleteTopic -t TopicTest -c DefaultCluster -n 192.168.0.1:9876
删除订阅组
sh mqadmin deleteSubGroup -g topicTestGroup -c DefaultCluster -n 192.168.0.1:9876
更新broker的属性配置
sh mqadmin updateBrokerConfig -c DefaultCluster -n 192.168.0.1:9876 -k listenPort -v 10911
#k是broker配置的key值,v是对应的value值
查看所有配置:
sh mqbroker -p >test.log
#注意指定定打印的文件,否则会把启动broker时读取的配置文件覆盖,该命令一定慎用
更新Topic权限
sh mqadmin updateTopicPerm -c DefaultCluster -n 192.168.0.1:9876 -p 6 -t TopicTest
-p 2:R(可读)、4:W(可写)、6:RW(可读可写)
查看Topic路由信息
sh mqadmin topicRoute -n 192.168.0.1:9876 -t TopicTest #结果会展示broker上报给name server的topic路由信息
查看Topic状态信息
sh mqadmin topicStatus -n 192.168.0.1:9876 -t TopicTest #Min Ofset:队列消息最小偏移量,Max Offset:队列的最大偏移位置,QID是哪条队列
查询Topic所属集群
sh mqadmin topicClusterList -n 192.168.0.1:9876 -t TopicTest
查看Broker运行状态信息
sh mqadmin brokerStatus -n 192.168.0.1:9876 -b 192.168.0.1:10911
-b 指定某个broker
-c 指定集群
根据消息ID查询消息
sh mqadmin queryMsgById -n 192.168.0.1:9876 -i C0A8649800002A9F0000000000000000
根据消息key查询消息(推荐)
sh mqadmin queryMsgByKey -n 192.168.0.1:9876 -t TopicTest -k a6ba52f404bc4926940c958d0c99fd4d #-k属性是发送的消息key值
根据消息的偏移值来查询消息
sh mqadmin queryMsgByOffset -n 192.168.0.1:9876 -o 0 -t TopicTest -i 0 -b broker-a
-o 队列偏移
-b Broker 名字
-i 队列ID
查看所有topic
sh mqadmin topicList -n 127.0.0.1:9876
查询集群消息
sh mqadmin clusterList -n 127.0.0.1:9876
查看所有消费组group
sh mqadmin consumerProgress -n 127.0.0.1:9876
查看指定消费组下的所有topic数据堆积情况
sh mqadmin consumerProgress -n 127.0.0.1:9876 -g warning-group
问题:WARN ScheduleMessageTimerThread - Offset not matched. Request offset: 1032133020, firstOffset: 888000000, lastOffset: 894000000, mappedFileSize: 6000000, mappedFiles count: 1
所有的主节点均有这报错,可以断定调度环节出问题了,由于offset远远超过最大offset而报错;没能将目标主题成功替换。
解决方法
先将broker节点的流量清除,2表示只写权限,4表示只读权限,6表示读写权限
#bin/mqadmin updateBrokerConfig -b brokerip:10911 -n nameserver地址:9876 -k brokerPermission -v 4
查看broker节点流量是否为0,需要等待broker完全没有流量了才可以进行关闭broker节点操作,以防止丢数据
#bin/mqadmin clusterList -n nameserver:9876
关闭broker节点进程
#bin/mqshutdown broker
将delayOffset.json 和delayOffset.json.bak文件拷走 此文件用于记录消费位点的,拷走后,重启应用进程会自动生产
#mv /data1/rocketmq/store/config/delayOffset.json* /data2/
将SCHEDULE_TOPIC_XXXX 文件拷走,用于调度任务,拷走后,重启应用进程会自动生产
#mv /data1/rocketmq/store/consumequeue/SCHEDULE_TOPIC_XXXX/ /data2/
将rocketmq的日志文件全部删除
#rm -rf /data2/logs/rocketmqlogs/*
然后将rocketmq进程启动
#cd /usr/local/rocketmq/bin/
#nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-2s-async/broker-a.properties &
把权限重新赋值
#bin/mqadmin updateBrokerConfig -b brokerip:10911 -n nameserver地址:9876 -k brokerPermission -v 6
等节点流量恢复重,按上面的操作,将集群所有主节点都操作一遍,就能正常消费数据了,且storeerror.log日志也没在报错了

浙公网安备 33010602011771号