简介
阿里出品,性能高但可视化页面太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端口,别忘了设置防火墙。
- 两台主机分别是192.168.1.88,192.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
192.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=192.168.1.88:9876;192.168.1.98:9876
#store存储路径,master与slave目录要不同
storePathRootDir=/opt/rocketmq/rocketmq/data/store
#commitLog存储路径
storePathCommitLog=/opt/rocketmq/rocketmq/data/store/commitlog
brokerIP1=192.168.1.88
#很重要 slave通信用
brokerIP2=192.168.1.88
broker-b-s.properties
brokerClusterName=DefaultCluster
brokerName=broker-b
brokerId=1
brokerIP1=192.168.1.88
deleteWhen=04
listenPort=10950
fileReservedTime=48
brokerRole=SLAVE
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.1.88:9876;192.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 &
192.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=192.168.1.98
brokerRole=SLAVE
namesrvAddr=192.168.1.88:9876;192.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=192.168.1.98
deleteWhen=04
fileReservedTime=48
namesrvAddr=192.168.1.88:9876;192.168.1.98:9876
storePathRootDir=/opt/rocketmq/rocketmq/data/store
storePathCommitLog=/opt/rocketmq/rocketmq/data/store/commitlog
brokerRole=SYNC_MASTER
flushDiskType=ASYNC_FLUSH
brokerIP2=192.168.1.98
配置详解
//集群名称,如果多个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 192.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测试
配置:
<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>
效果