简介
阿里出品,性能高但可视化页面太low,商用的的话,要求真正的懂她(阿里有商用版,在阿里云可以购买)
集群支持
RocketMQ天生对集群的支持非常友好
单Master:
- 优点:除了配置简单没什么优点
- 缺点:不可靠,该机器重启或宕机,将导致整个服务不可用
多Master:
- 优点:配置简单,性能最高
- 缺点:可能会有少量消息丢失(配置相关),单台机器重启或宕机期间,该机器下未被消费的消息在机器恢复前不可订阅,影响消息实时性
- 多Master多Slave异步模式:
每个Master配一个Slave,有多对Master-Slave,集群采用异步复制方式,主备有短暂消息延迟,毫秒级
- 优点:性能同多Master几乎一样,实时性高,主备间切换对应用透明,不需人工干预
- 缺点:Master宕机或磁盘损坏时会有少量消息丢失
多Master多Slave同步模式:
每个Master配一个Slave,有多对Master-Slave,集群采用同步双写方式,主备都写成功,向应用返回成功
- 优点:服务可用性与数据可用性非常高
- 缺点:性能比异步集群略低,当前版本主宕备不能自动切换为主。
需要注意的是,在RocketMQ里面,1台机器只能要么是Master,要么是Slave。这个在初始的机器配置里面,就定死了。不会像kafka那样存在master动态选举的功能。其中Master的broker id = 0,Slave的broker id > 0。有点类似于mysql的主从概念,master挂了以后,slave仍然可以提供读服务,但是由于有多主的存在,当一个master挂了以后,可以写到其他的master上。
集群搭建:2M-2S-SYNC(两主两从同步写)
环境准备
- 环境准备:rocket-4.7.0 ,JDK1.8 并配置好环境变量
- 定好4个节点的端口,我这里主节点为默认10911,从节点设置成 10950,另外nameserver都是默认9876端口,别忘了设置防火墙。
- 两台主机分别是152.168.1.88,152.168.1.98(4个节点)
修改参数和创建数据存储路径
设置好节点的数据存储路径
mkdir /opt/rocketmq/rocketmq/data
mkdir /opt/rocketmq/rocketmq/data /store 存储路径
mkdir /opt/rocketmq/rocketmq/data /store/commitlog //commitLog 存储路径
mkdir /opt/rocketmq/rocketmq/data a/store/consumequeue //消费队列存储路径存储路径
mkdir /opt/rocketmq/rocketmq/data /store/index //消息索引存储路径
记得修改两台机器上的 runbroker.sh 与 runserver.sh 的虚拟机参数。
runbroker.sh:
runserver.sh
修改xml文件配置:
进出$ROCKETMQ-HOME/conf目录执行如下命令:
sed -i 's#${user.home}#/opt/rocketmq/rocketmq#g' *.xml
152.168.1.88主机
用于broker-a的主,broker-b的从,分别对应如下2个文件:
${ROCKETMQ-HOME}/conf/2m-2s-sync/broker-a.properties
${ROCKETMQ-HOME}/conf/2m-2s-sync/broker-b-s.properties
Ps
建议在/etc/hosts配置域名,在以下文件中使用域名
broker-a.properties
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=SYNC_MASTER
flushDiskType=ASYNC_FLUSH
namesrvAddr=152.168.1.88:9876;152.168.1.98:9876
#store存储路径,master与slave目录要不同
storePathRootDir=/opt/rocketmq/rocketmq/data/store
#commitLog存储路径
storePathCommitLog=/opt/rocketmq/rocketmq/data/store/commitlog
brokerIP1=152.168.1.88
#很重要 slave通信用
brokerIP2=152.168.1.98
broker-b-s.properties
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=1
brokerIP1=152.168.1.88
deleteWhen=04
listenPort=10950
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
namesrvAddr=152.168.1.88:9876;152.168.1.98:9876
storePathRootDir=/opt/rocketmq/rocketmq/data/store/slave
storePathCommitLog=/opt/rocketmq/rocketmq/data/store/slave/commitlog
然后分别执行:
nohup sh mqnamesrv &
nohup sh mqbroker -c ../conf/2m-2s-sync/broker-a.properties &
nohup sh mqbroker -c ../conf/2m-2s-sync/broker-b-s.properties &
152.168.1.98主机
用于broker-b的主,broker-a的从,分别对应如下2个文件:
${ROCKETMQ-HOME}/conf/2m-2s-sync/broker-a-s.properties
${ROCKETMQ-HOME}/conf/2m-2s-sync/broker-b.properties
broker-a-s.properties
brokerClusterName=DefaultCluster
brokerName=broker-a
listenPort=10950
brokerId=1
deleteWhen=04
fileReservedTime=48
brokerIP1=152.168.1.98
brokerRole=SLAVE
namesrvAddr=152.168.1.88:9876;152.168.1.98:9876
storePathRootDir=/opt/rocketmq/rocketmq/data/store/slave
storePathCommitLog=/opt/rocketmq/rocketmq/data/store/slave/commitlog
flushDiskType=ASYNC_FLUSH
broker-b.properties
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=0
brokerIP1=152.168.1.98
deleteWhen=04
fileReservedTime=48
namesrvAddr=152.168.1.88:9876;152.168.1.98:9876
storePathRootDir=/opt/rocketmq/rocketmq/data/store
storePathCommitLog=/opt/rocketmq/rocketmq/data/store/commitlog
brokerRole=SYNC_MASTER
flushDiskType=ASYNC_FLUSH
brokerIP2=152.168.1.88
配置详解
//集群名称,如果多个master,那么每个master配置的名称应该一致,要不然识别不了
brokerClusterName=rocketmq-cluster
//broker名称
brokerName=broker-a
//0 表示master,>0 表示slave
brokerId=0
//nameServer地址,分号隔开,生产环境使用域名(好维护)
namesrvAddr=192.168.5.100:9876;192.168.5.101:9876
//在发送消息时,自动创建服务器不存在的topic,默认创建的队列数
defaultTopicQueueNums=4
//是否允许broker自动创建topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
//是否允许broker自动创建订阅组,建议线下开始,线上关闭
autoCreateSubscriptionGroup=true
//broker对外服务的监听端口,
//同一台机器部署多个broker,端口号要不同,且端口号之间要相距大些(主节点)
listenPort=10911
//删除文件的时间节点,默认凌晨4点
deleteWhen=04
//文件保留时间,默认48小时
fileReservedTime=48
//commitLog每个文件的大小,默认大小1g
mapedFileSizeCommitLog=1073741824
//consumeQueue每个文件默认存30w条,根据自身业务进行调整
mapedFileSizeConsumeQueue=300000
destroyMapedFileInterval=120000
redeleteHangedFileInterval=120000
//检查物理文件磁盘空间
diskMaxUsedSpaceRatio=88
//store存储路径,master与slave目录要不同
storePathRootDir=/mysoft/rocketmq/data/store
//commitLog存储路径
storePathCommitLog=/mysoft/rocketmq/data/store/commitlog
//限制的消息大小
maxMessageSize=65536
flushCommitLogLeastPages=4
flushConsumeQueueLeastPages=2
flushCommitLogThoroughInterval=10000
flushConsumeQueueThoroughInterval=60000
checkTransactionMessageEnable=false
//发消息线程池数
sendMessageThreadPoolNums=128
//拉去消息线程池数
pullMessageThreadPoolNums=128
//broker角色:
//ASYSC_MASTER 异步复制master
//SYSC_MASTER 同步复制master
//SLAVE 从
brokerRole=SYSC_MASTER
///刷盘方式
//ASYNC_FLUSH 异步刷盘
//SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
启动
nohup sh mqnamesrv &
nohup sh mqbroker -c ../conf/2m-2s-sync/broker-a-s.properties &
nohup sh mqbroker -c ../conf/2m-2s-sync/broker-b.properties &
验证
sh mqadmin clusterlist -n 152.168.1.88:9876
配置参考
Broker参数
■Broker配置参数 |
|
|
|
# |
参数名 |
默认值 |
说明 |
2 |
listenPort |
10911 |
broker的服务端口号,作为对producer和consumer使用服务的端口号 |
3 |
namesrvAddr |
null |
namesrv的ip地址。格式: ip:port;ip:port |
4 |
brokerIP1 |
本机IP |
broker所在的机器ip,默认不用设置,如果机器有多个网卡,需要手动设置 |
5 |
brokerName |
本机主机名 |
作用为一组master与slave通过brokerName是否相同来标示,通过brokerId来区分master还是slave |
6 |
brokerClusterName |
DefaultCluster |
整个broker集群的名字,创建topic时需要指定。 |
7 |
brokerId |
0 |
0:master 非0:slave |
8 |
storePathCommitLog |
$HOME/store/commitlog/ |
commitLog存储路径 |
9 |
storePathConsumerQueue |
$HOME/store/consumequeue/ |
消费队列存储路径 |
10 |
mapedFileSizeCommitLog |
1024 * 1024 * 1024(1G) |
commitLog每个文件的大小,默认1G |
11 |
deleteWhen |
4 |
删除文件时间点,默认凌晨 4点 |
12 |
fileReservedTime |
72 |
文件保留时间,默认72小时. |
13 |
brokerRole |
ASYNC_MASTER |
Broker 的角色 |
14 |
flushDiskType |
ASYNC_FLUSH |
刷盘方式 |
15 |
defaultTopicQueueNums |
4 |
在发送消息时,自动创建服务器不存在的topic,默认创建的队列数。 |
16 |
autoCreateTopicEnable |
true |
是否自动创建topic。 |
17 |
autoCreateSubscriptionGroup |
true |
是否允许Broker自动创建订阅组,建议线下开启,线上关闭 |
18 |
rejectTransactionMessage |
false |
是否拒绝事务消息接入 |
19 |
etchNamesrvAddrByAddressServer |
false |
是否从web服务器获取Name Server地址,针对大规模的Broker集群建议使用这种方式 |
20 |
storePathIndex |
$HOME/store/index |
消息索引存储路径 |
21 |
storeCheckpoint |
$HOME/store/checkpoint |
checkpoint文件存储路径 |
22 |
abortFile |
$HOME/store/abort |
abort文件存储路径 |
23 |
maxTransferBytesOnMessageInMemory |
262144 |
单次Pull消息(内存)传输的最大字节数 |
24 |
maxTransferCountOnMessageInMemory |
32 |
单次Pull消息(内存)传输的最大条数 |
25 |
maxTransferBytesOnMessageInDisk |
65536 |
单次Pull消息(磁盘)传输的最大字节数 |
26 |
maxTransferCountOnMessageInDisk |
8 |
单次Pull消息(磁盘)传输的最大条数 |
27 |
messageIndexEnable |
true |
是否开启消息索引功能 |
28 |
messageIndexSafe |
false |
是否提供安全的消息索引机制,索引保证不丢 |
29 |
haMasterAddress |
|
在Slave上直接设置Master地址,默认从Name Server上自动获取,也可以手工强制配置 |
30 |
cleanFileForciblyEnable |
true |
磁盘满、且无过期文件情况下 TRUE 表示强制删除文件,优先保证服务可用 FALSE 标记服务不可用,文件不删除 |
Consumer参数
DefaultMQProducer、TransactionMQProducer、DefaultMQPushConsumer、DefaultMQPullConsumer都继承与ClientConfig类,
|
|||
■客户端的公共配置 |
|
|
|
# |
参数名 |
默认值 |
说明 |
1 |
namesrvAddr |
|
Name Server地址列表,多个NameServer地址用分号隔开 |
2 |
clientIP |
本机IP |
客户端本机IP地址,某些机器会发生无法识别客户端IP地址情况,需要应用在代码中强制指定 |
3 |
instanceName |
DEFAULT |
客户端实例名称,客户端创建的多个Producer、Consumer实际是共用一个内部实例(这个实例包含网络连接、线程资源等) |
4 |
clientCallbackExecutorThreads |
4 |
通信层异步回调线程数 |
5 |
pollNameServerInteval |
30000 |
轮询Name Server间隔时间,单位毫秒 |
6 |
heartbeatBrokerInterval |
30000 |
向Broker发送心跳间隔时间,单位毫秒 |
7 |
persistConsumerOffsetInterval |
5000 |
持久化Consumer消费进度间隔时间,单位毫秒 |
Producer参数
■Producer配置 |
|||
# |
参数名 |
默认值 |
说明 |
1 |
producerGroup |
DEFAULT_PRODUCER |
Producer组名,多个Producer如果属于一个应用,发送同样的消息,则应该将它们归为同一组 |
2 |
createTopicKey |
TBW102 |
在发送消息时,自动创建服务器不存在的topic,需要指定Key。 |
3 |
defaultTopicQueueNums |
4 |
在发送消息时,自动创建服务器不存在的topic,默认创建的队列数 |
4 |
sendMsgTimeout |
10000 |
发送消息超时时间,单位毫秒 |
5 |
compressMsgBodyOverHowmuch |
4096 |
消息Body超过多大开始压缩(Consumer收到消息会自动解压缩),单位字节 |
6 |
retryAnotherBrokerWhenNotStoreOK |
FALSE |
如果发送消息返回sendResult,但是sendStatus!=SEND_OK,是否重试发送 |
7 |
maxMessageSize |
131072 |
客户端限制的消息大小,超过报错,同时服务端也会限制 |
8 |
transactionCheckListener |
|
事务消息回查监听器,如果发送事务消息,必须设置 |
9 |
checkThreadPoolMinSize |
1 |
Broker回查Producer事务状态时,线程池大小 |
10 |
checkThreadPoolMaxSize |
|
Broker回查Producer事务状态时,线程池大小 |
11 |
checkRequestHoldMax |
2000 |
Broker回查Producer事务状态时,Producer本地缓冲请求队列大小 |
|
|
|
|
■Push Consumer配置 |
|
|
|
# |
参数名 |
默认值 |
说明 |
1 |
consumerGroup |
DEFAULT_CONSUMER |
Consumer组名,多个Consumer如果属于一个应用,订阅同样的消息,且消费逻辑一致,则应该将它们归为同一组 |
2 |
messageModel |
CLUSTERING |
消息模型,支持以下两种 |
3 |
consumeFromWhere |
CONSUME_FROM_LAST_OFFSET |
Consumer启动后,默认从什么位置开始消费 |
4 |
allocateMessageQueueStrategy |
AllocateMessageQueueAveragely |
Rebalance算法实现策略 |
5 |
subscription |
{} |
订阅关系 |
6 |
messageListener |
|
消息监听器 |
7 |
offsetStore |
|
消费进度存储 |
8 |
consumeThreadMin |
10 |
消费线程池数量 |
9 |
consumeThreadMax |
20 |
消费线程池数量 |
10 |
consumeConcurrentlyMaxSpan |
2000 |
单队列并行消费允许的最大跨度 |
11 |
pullThresholdForQueue |
1000 |
拉消息本地队列缓存消息最大数 |
12 |
pullInterval |
0 |
拉消息间隔,由于是长轮询,所以为0,但是如果应用为了流控,也可以设置大于0的值,单位毫秒 |
13 |
consumeMessageBatchMaxSize |
1 |
批量消费,一次消费多少条消息 |
14 |
pullBatchSize |
32 |
批量拉消息,一次最多拉多少条 |
|
|
|
|
■Pull Consumer配置 |
|
|
|
# |
参数名 |
默认值 |
说明 |
1 |
consumerGroup |
DEFAULT_CONSUMER |
Consumer组名,多个Consumer如果属于一个应用,订阅同样的消息,且消费逻辑一致,则应该将它们归为同一组 |
2 |
brokerSuspendMaxTimeMillis |
20000 |
长轮询,Consumer拉消息请求在Broker挂起最长时间,单位毫秒 |
3 |
consumerTimeoutMillisWhenSuspend |
30000 |
长轮询,Consumer拉消息请求在Broker挂起超过指定时间,客户端认为超时,单位毫秒 |
4 |
consumerPullTimeoutMillis |
10000 |
非长轮询,拉消息超时时间,单位毫秒 |
5 |
messageModel |
BROADCASTING |
消息模型,支持以下两种 |
6 |
messageQueueListener |
|
监听队列变化 |
7 |
offsetStore |
|
消费进度存储 |
8 |
registerTopics |
[] |
注册的topic集合 |
9 |
allocateMessageQueueStrategy |
AllocateMessageQueueAveragely |
Rebalance算法实现策略 |
Meesage数据结构
Message数据结构各个字段都可以通过get、set方式访问,例如访问topic: |
|||
字段名 |
默认值 |
必填 |
说明 |
Topic |
null |
○ |
线下环境不需要申请,线上环境需要申请后才能使用 |
Body |
null |
○ |
二进制形式,序列化由应用决定,Producer与Consumer要协商好序列化形式。 |
Tags |
null |
|
类似于Gmail为每封邮件设置的标签,方便服务器过滤使用。目前只支持每个消息设置一个tag,所以也可以类比为Notify的MessageType概念。 |
Keys |
null |
|
代表这条消息的业务关键词,服务器会根据keys创建哈希索引,设置后,可以再Console系统根据Topic、Keys来查询消息,由于是哈希索引,请尽可能保证key唯一,例如订单号,商品ID等。 |
Flag |
0 |
|
完全由应用来设置,RocketMQ不做敢于。 |
DelayTimeLevel |
0 |
|
消息延时级别,0表示不延时,大于0会延时特定的时间才会被消费。 |
WaitStoreMsgOK |
TRUE |
|
表示消息是否在服务器罗盘后才返回应答。 |
Java代码测试
Springboot+netty+rocketmq测试
配置:
rocketmq.name-server=152.168.1.88:9876
rocketmq.producer.group=rocketmq-group
rocketmq.producer.send-message-timeout=5000
依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.32.Final</version>
</dependency>
<!--rocketMq依赖-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.3</version>
</dependency>
效果