Rocketmq 集群部署-顺序消息-并发消息-压力测试

1.部署Rocketmq

1.1 配置安装

参考使用手册

1.1.1 修改配置

修改hosts

vim /etc/hosts

172.22.31.94    rocketmq-nameserver01
172.22.31.95    rocketmq-nameserver02
172.22.31.94    rocketmq-master01
172.22.31.95    rocketmq-master02

配置2master无slave

vim conf/2m-noslave/broker-01.properties

#所属集群名字
brokerClusterName=xdf-oc-t
#broker名字,注意此处不同的配置文件填写的不一样
brokerName=broker-01
#0 表示 Master,>0 表示 Slave
brokerId=0
#nameServer地址,分号分割
namesrvAddr=rocketmq-nameserver01:9876;rocketmq-nameserver02:9876
#在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=64
#是否允许 Broker 自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许 Broker 自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#Broker 对外服务的监听端口
listenPort=10911
#删除文件时间点,默认凌晨 4点
deleteWhen=04
#文件保留时间,默认 48 小时
fileReservedTime=48
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog=1073741824
#ConsumeQueue每个文件默认存30W条,根据业务情况调整
mapedFileSizeConsumeQueue=300000
#destroyMapedFileIntervalForcibly=120000
#redeleteHangedFileInterval=120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio=88
#存储路径
storePathRootDir=/neworiental/rocketmq/store
#commitLog 存储路径
storePathCommitLog=/neworiental/rocketmq/store/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue=/neworiental/rocketmq/store/consumequeue
#消息索引存储路径
storePathIndex=/neworiental/rocketmq/store/index
#checkpoint 文件存储路径
storeCheckpoint=/neworiental/rocketmq/store/checkpoint
#abort 文件存储路径
abortFile=/neworiental/rocketmq/store/abort
#限制的消息大小
maxMessageSize=65536
#flushCommitLogLeastPages=4
#flushConsumeQueueLeastPages=2
#flushCommitLogThoroughInterval=10000
#flushConsumeQueueThoroughInterval=60000
#Broker 的角色
#- ASYNC_MASTER  异步复制Master
#- SYNC_MASTER  同步双写Master
#- SLAVE
brokerRole=ASYNC_MASTER
#刷盘方式
#- ASYNC_FLUSH  异步刷盘
#- SYNC_FLUSH  同步刷盘
flushDiskType=ASYNC_FLUSH
#checkTransactionMessageEnable=false
#发消息线程池数量
sendMessageThreadPoolNums=128
#发送消息是否使用可重入锁
useReentrantLockWhenPutMessage=true
#拉消息线程池数量
#pullMessageThreadPoolNums=128

需要以下两项配置,不然多线程发送报错:[TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while

#发消息线程池数量
sendMessageThreadPoolNums=128
#发送消息是否使用可重入锁
useReentrantLockWhenPutMessage=true

1.1.3 修改启动脚本jvm参数

vim runbroker.sh; vim runserver.sh

1.2 启动服务

1.2.1 启动namesrv

94/95两台机器上分别启动

nohup sh mqnamesrv >/dev/null 2>&1 &

1.2.2 启动broker

94/95两台机器上分别启动

nohup sh mqbroker -c /neworiental/rocketmq/rocketmq-4.6.1/conf/2m-noslave/broker-01.properties >/dev/null 2>&1 &

nohup sh mqbroker -c /neworiental/rocketmq/rocketmq-4.6.1/conf/2m-noslave/broker-02.properties >/dev/null 2>&1 &

1.2.3 启动console

docker run -d --restart always --name rocketmq-console \
 -e "JAVA_OPTS=-Drocketmq.namesrv.addr=172.22.31.94:9876;172.22.31.95:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \
-p 8080:8080 -t styletang/rocketmq-console-ng

2.压力测试

2.1 服务器配置

4台服务器配置 12c32g,2台mq,生产消费个1台;

2.2 模拟订单场景-严格顺序消息

2.2.1 配置简介

mq集群:两台机器部署,2m-noslave;2 namesrv;

顺序消息:单条消息模拟网报订单对象5k大小;

2.2.2 顺序消息

  • Rocketmq 将消息路由到1台 broker,同一个orderId 的消息路由到同一个队列,从而保证顺序消息;但是无法利用多节点资源,通过配置多个 topic 路由到多个broker,充分利用多节点资源;
  • 使用redis分布式锁 + 同一个订单根据订单号取模路由到同一个 topic 下的同一个 queue 保证顺序消息。

2.2.3 程序简介

  • producer,100线程,4 topic;consumer,100线程,模拟入库耗时20ms;
  • 设定100个线程,每个线程循环10000次,总共次数100w,与订单数量取模,保证订单数量小于等于2000。
  • 每个订单操作的次数 orderUpdates = thread * circleCounts/orderCount=500次。
thread circleCounts orderCount orderUpdates
100 10000 2000 500

2.2.4 操作步骤

--首先启动消费注册到namesrv
nohup java -jar amqp.jar --spring.profiles.active=ordered-rmq-c > consumer.log 2>&1 &
--后启动生产
nohup java -jar amqp.jar --spring.profiles.active=ordered-rmq-p > producer.log 2>&1 &

--删除order_code
redis-cli -h 10.202.80.118 -p 7921 -a do7l8KMbwuta keys "order_code*" | xargs -I {} redis-cli -h 10.202.80.118 -p 7921 -a do7l8KMbwuta  del {}

redis-cli -a do7l8KMbwuta -h 10.202.80.118 -p 7921

--杀掉进程&删除日志
ps -ef|grep amqp | grep -v grep | awk '{print $2}'|xargs kill -9 && rm -rf *log*

-- 查看同一订单的顺序
cat logs/spring-rabbit/INFO/2020-03-13.log | grep order_code_0 >  order_code_0

2.2.5 测试结果

(a) topic 下 64 queue

进程数量 生产消息tps 消费消息tps 2个broker/cpu producer/cpu consumer/cpu
1 8k+ 5-6k 2-3% 40% 10%
2 10K+ 6K+ 2-3% 55% 15%

(b) topic 下 128 queue

修改queue的数量,先控制台修改topic配置,然后程序修改topic配置

进程数量 生产消息tps 消费消息tps 2个broker/cpu producer/cpu consumer/cpu
1 8k+ 5-6k 2-3% 38% 10%
2 10k+ 8k+ 2-4% 55% 18%

© 小结:

  • 增加生产进程,生产消息tps无明显提升,2个生产者时同一订单的并发量增加2倍,查看日志发现获取redis分布式锁的时间成几何倍数增加,所以生产消息无明显提升。

  • 增加topic下queue的数量,理论上提高了并发度,测试发现消费消息tps提高2k,生产消息tps未提高,大部分耗时在获取redis分布式锁。

  • 正常操作一般是下单、支付、撤单、转退班(XDF特有)、优惠重算(XDF特有)等几个动作,生产环境几乎不存在同一订单操作500次,理论上 tps 高于压测值。

2.2.6 arthas火焰图优化

  • 启动arthas,开启火焰图

java -jar arthas-boot.jar

profiler start

profiler stop

  • 火焰图分析

logback占比26%左右,Logger.info 占比20%,Logger.debug 占比 6%

  • 程序分析
    分别配置(20/100线程*10000次)发送订单消息,有无日志时间对比如下:

20发送线程,有/无日志打印对比,71s:58s,日志占比18.3%

100发送线程,有/无日志打印对比,144s:129s,日志占比10.4%

2.3 benchmark测试-并发消息

128线程,5k数据包

2.3.1 操作步骤

sh producer.sh -n 172.22.31.94:9876;172.22.31.95:9876 -w 128 -s 5000
sh consumer.sh -n 172.22.31.94:9876;172.22.31.95:9876 

2.3.2 测试结果

进程/线程数量 生产消息tps Average RT Max RT 消费消息tps 2个broker/cpu producer/cpu consumer/cpu
1/128 50-60k 1.2 298 50-60k 15% 11% 13%
2/128 60-80k 1.6 1516 60-80k 20-30% 20% 27%

你可能感兴趣的:(集群-分布式,Java框架)