RocketMQ 的下载及安装
一、MQ的比较
Kafka | RocketMQ | RabbitMQ | |
设计定位 |
系统间的数据管道,实时数据处理; 例如:收集日志、监控数据、网站活跃性跟踪、常规消息系统 |
非日志的可靠性消息传递; 例如:电商系统、订单、交易、消息推送、bin-log分发等 |
可靠消息传递;和 RocketMQ类似 |
成熟度 | 日志领域成熟 | 成熟 | 成熟 |
开发语言 | Scala | Java | Erlang |
支持协议 | 一套 自行设计的基于TCP的二进制协议 | 自定义的一套 | AMQP |
客户端语言 | C/C++、Python、Go、Erlang、Ruby等 | Java | Java、C++、Python、PHP等 |
持久化方式 | 磁盘 | 磁盘 | 内存、文件 |
集群管理 | Zookeeper | Name server | ------ |
选主方式 | 从 ISR 中选举一个 leader |
不支持自动选主; 通过设定 broker name、broker Id 实现;borker name 相同,borker id=0 时为 master,其他为 slave |
最早加入 集群的 Broker |
可用性 |
非常高 分布式、主从 |
非常高 分布式、主从 |
高 主从,采用镜像模式实现,数据量大时可能产生性能瓶颈 |
主从切换 |
自动切换 N个副本,允许N-1个时效,master时效后自动从 ISR 中选择一个主 |
不支持自动切换 master 时效后不能向 master 发消息,消费者大概 30s 感知到此事件,此后从 slave 消费;如果 master 无法恢复,异步复制时可能出现部分信息丢失 |
自动切换 最早加入的集群的节点为master;因为新加入的 slave 不会同步 master 之前的数据,所以可能出现部分数据丢失 |
数据可靠性 |
很好 支持生成者单条发送、同步刷盘、同步复制,但是这种场景下性能明显下降 |
很好 生成者单条发送,broker同步刷盘、异步刷盘、 同步双写,异步复制 |
好 生产者支持同步 / 异步ACK;支持队列数据持久化,镜像模式中支持主从同步 |
消息写入性能 |
非常好 每条10个字节测试:百万条/s; |
很好 每条10个字节测试:单机单borker约7w/s,单机3borker约12w/s |
RAM 约为 RocketMQ的 1/2; Disk性能约为RokcetMQ的 1/3; |
性能稳定性 |
队列/分区 多时性能不稳定,明显下降; 消息堆积时性能稳定; 当单机的 topic 的数量超过 64 个,则性能下降特别厉害; |
队列较多、消息堆积时性能稳定; 单机的 队列数量支持 5w,topic 的增加不影响性能; |
消息堆积时性能不稳定,明显下降 |
复制备份 |
消息先写入 leader 的 log,follwers 从 leader 中 pull 到数据以后先 ACK leader,再写入 log; ISR 维护与 leader 同步的列表,落后太多的 follwer 被删除掉 |
同步双写 异步复制:slave 启动线程从 master 中拉数据 |
普通模式下不复制 镜像模式下:消息先到master,然后写入到 slave 上;入集群之前的消息不会被复制到新的 slave 上 |
消息投递实时性 |
毫秒级 具体由消费者轮询间隔时间决定 |
毫秒级 支持pull、push两种模式、延时通常在毫秒级 |
毫秒级 |
顺序消费 |
支持顺序消费 但是一台broker宕机后,就会产生消息乱序 |
支持顺序消费 在顺序消费场景下,消费失败时消费队列将会暂停 |
支持顺序消费 但是如果一个消息消费失败哦,此消息的顺序将会被打乱 |
定时消息 |
不支持 |
开源版本仅支持定时 Level |
不支持 |
事务消息 | 不支持 | 支持 | 不支持 |
Broker端消息过滤 | 不支持 |
支持 通过 tag 过滤,类似于 topic |
不支持 |
消息查询 | 不支持 |
支持 根据 messageId 查询 支持根据 mesageKey 查询消息 |
不支持 |
消息失败重试 |
不支持失败重试 offset存储在consumer中,无法保证 |
支持失败重试 offset 存储在 broker 中 |
支持失败重试 |
消息重新消费 |
支持通过修改 offset 来重新消费 |
支持按照时间来重新消费 |
|
发送端负载均衡 | 可自由指定 | 可自由指定 | 需要单独 LoadBanlance |
消费方式 | consumer pull | consumer pull / broker push | broker push |
批量发送 |
支持 默认 producer 缓存、压缩,然后批量发送 |
不支持 | 不支持 |
消息清理 | 指定文件保存时间,过期删除 | 指定文件保存时间,过期删除 | 默认可用内存少于40%,触发GC,GC时找到两个相同的文件,合并right到left |
访问权限控制 | 无 | 无 | 类似于数据库,需要配置用户名和密码 |
管理后台 | 官网不提供;第三方开源管理工具可供使用 | 官网提供;rocketmq-dashboard | 官网提供;rabbitmq-admin |
管理后台的功能 |
Kafka Web Conslole Broker列表;Kafka集群中 Topic列表; |
Cluster、Topic、Connection、NameServer、MessageBroker、Offset、Consumer | OverView、Conections、channels、exchanges、queues、admin |
优点 |
1、高吞吐、低延迟、高可用、集群热扩展、集群容错上由很好的表现; 2、producer 端提供缓存、压缩功能,可节省性能,提高效率; 3、提供顺序消费能力; 4、提供多种客户端语言; 5、生态完善,在大数据处理方面有大量配套的设施; |
1、在高吞吐、低延迟、高可用上有非常好的表现;消息堆积时,性能也好; 2、api、系统设计都更加适合在业务处理场景; 3、支持多种消费方式; 4、支持 Broker 消息过滤; 5、支持事务; 6、提供消息顺序消费能力;Consumer 可以水平扩展,消费能力很强; 7、集群规模在 50 台左右,单日处理消息上百亿;经历过大数据量的考验,比较稳定可靠; |
1、在高吞吐量、高可用较前俩者有所不如; 2、支持多种客户端语言;支持AMQP协议; 3、由于 Erlang 语言的特性,性能也比较好;使用 RAM 模式时,性能很好; 4、管理界面较丰富,在互联网公司也有较大规模的应用; |
缺点 |
1、消费集群数目受到分区数目的限制; 2、单机topic多时,性能会明显降低; 3、不支持事务; |
1、相比于 Kafka,使用者较少,生态不够完善;消费堆积、吞吐率上也有所不如; 2、不支持主从自动切换,master 时效后,消费者要一定时间才能感知; 3、客户端只支持Java; |
1、Erlang 语言难度较大;集群不支持动态扩展; 2、不支持事务、消息吞吐能力有限; 3、消息堆积时,性能明显下降; |
二、RocketMQ 的安装
1、 下载 RocketMQ 的包;
wget https://mirrors.tuna.tsinghua.edu.cn/apache/rocketmq/4.9.4/rocketmq-all-4.9.4-bin-release.zip --no-check-certificate
2、 解压缩
unzip rocketmq-all-4.9.4-bin-release.zip
3、配置环境变量
vim /etc/profile # 在文件末尾添加以下内容: export ROCKETMQ_HOME=/usr1/rocketmq export PATH=$ROCKETMQ_HOME/bin:$PATH
4、修改完后,让环境变量立即生效
source /etc/profile
5、修改 RocketMQ 使用的内存
rocketmq需要启动两个服务:
- name server:默认配置JVM使用的内存是4G;
- broker:默认配置JVM使用的内存是8G, 内存设置的过大,可能导致开发环境中内存不足,服务无法启动,可以通过适当降低两个服务的内存解决.
早期rocketmq使用的注册中心是zookeeper, 但由于它包含的功能过于强大, 而rocketmq使用zookeeper包含的内容过于丰富,导致我们在使用时往往需要搭建zookeeper的服务,以致后来rocketmq自己开发了符合自己应用场景的注册服务,name server和broker;
(1)修改name server内存256m;
cd /usr1/rocketmq/bin # 编辑 runserver.sh vim runserver.sh # 找到文件中下面这一行: JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" # 将 -Xms4g -Xmx4g -Xmn2g 修改为 -Xms256m -Xmx256m -Xmn128m JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
(2)修改broker内存256m;
# 编辑 runbroker.sh vim runbroker.sh # 找到文件中下面这一行: JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g" # 将 -Xms8g -Xmx8g -Xmn4g 修改为 -Xms256m -Xmx256m -Xmn128m JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"
6、启动RocketMQ
(1)先启动name server;
# 进入 rocketmq的 bin 目录 cd /usr1/rocketmq/bin/ # 启动 name server nohup sh mqnamesrv & # 查看运行日志, 看到"The Name Server boot success."表示启动成功 tail -f nohup.out
(2)再启动broker;
# 然后我们需要找到编辑 conf/broker.conf vim /usr1/rocketmq/conf/broker.conf # 加入一个配置,自动创建 topic: autoCreateTopicEnable=true
# 配置IP
brokerIPl=192.168.172.20 # 启动 broker, 并连接到name server;localhost:9876 cd /usr1/rocketmq/bin/ nohup sh mqbroker -n localhost:9876 & # 查看运行日志, 看到"The broker[......:10911] boot success."表示启动成功 tail -f nohup.out
Broker的配置说明:
# rocketmq-name服务地址,多个地址用;分开,不配置默认为localhost:9876 namesrvAddr = 192.168.241.198:9876;192.168.241.199:9876 # 可以配置成自己需要的名称 brokerClusterName = DefaultCluster # 搭建集群的时候 Master 和 Slave 的 brokerName 要配置的一样 brokerName = broker-b # brokeId=0,表示为 Master 节点;所有的 非0 节点都为 Slave brokerId = 0 # 每天的凌晨 4 点删除消息 deleteWhen = 04 # 数据存在磁盘上最多 48 小时 fileReservedTime = 48 # 当前节点角色;消息同步到Slave之后再响应 brokerRole = SYNC_MASTER # 刷盘的策略; # 同步刷盘:消息写到缓冲区之后,立刻通知线程去进行刷盘,刷盘成功之后再响应成功; # 异步刷盘,消息先写到缓冲区之后,缓冲区的大小到达指定的保准之后去通知线程进行刷盘;异步刷盘可能造成数据丢失; flushDiskType = ASYNC_FLUSH # 自动创建 topic autoCreateTopicEnable=true # broker通信端口,默认端口 listenPort=10911 storePathRootDir=/root/rocketmq/store-m storePathCommitLog=/root/rocketmq/store-m/store/commitlog
7、命令行快速验证
在RocketMQ的安装包中,提供了一个tools.sh工具可以用来在命令行快速验证RocketMQ服务。我们在worker2上进入RocketMQ的安装目录: 首先需要配置一个环境变量NAMESRV_ADDR指向我们启动的NameServer服务。 export NAMESRV_ADDR='localhost:9876' 然后启动消息生产者发送消息:默认会发1000条消息 bin/tools.sh org.apache.rocketmq.example.quickstart.Producer 我们可以看到发送消息的日志: ..... SendResult [sendStatus=SEND_OK, msgId=C0A8E88007AC3764951D891CE9A003E7, offsetMsgId=C0A8E88000002A9F00000000000317BF, messageQueue=MessageQueue [topic=TopicTest, brokerName=worker1, queueId=1], queueOffset=249] 14:59:33.418 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[127.0.0.1:9876] result: true 14:59:33.423 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[192.168.232.128:10911] result: true 这日志中,上面部分就是我们发送的消息的内容。后面两句标识消息生产者正常关闭。 然后启动消息消费者接收消息: bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer 启动后,可以看到消费到的消息。 ...... ConsumeMessageThread_19 Receive New Messages: [MessageExt [brokerName=worker1, queueId=2, storeSize=203, queueOffset=53, sysFlag=0, bornTimestamp=1606460371999, bornHost=/192.168.232.128:43436, storeTimestamp=1606460372000, storeHost=/192.168.232.128:10911, msgId=C0A8E88000002A9F000000000000A7AE, commitLogOffset=42926, bodyCRC=1968636794, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='TopicTest', flag=0, properties={MIN_OFFSET=0, MAX_OFFSET=250, CONSUME_START_TIME=1606460450150, UNIQ_KEY=C0A8E88007AC3764951D891CE41F00D4, CLUSTER=DefaultCluster, WAIT=true, TAGS=TagA}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107, 101, 116, 77, 81, 32, 50, 49, 50], transactionId='null'}]] 日志中MessageExt后的整个内容就是一条完整的RocketMQ消息。我们要对这个消息的结构有个大概的了解,后面会对这个消息进行深入的理解。 其中比较关键的属性有:brokerName,queueId,msgId,topic,cluster,tags,body,transactionId。先找下这些属性在哪里。 而这个Consume指令并不会结束,他会继续挂起,等待消费其他的消息。我们可以使用CTRL+C停止该进程。
8、关闭RocketMQ服务
要关闭RocketMQ服务可以通过mqshutdown脚本直接关闭 # 1.关闭NameServer sh bin/mqshutdown namesrv # 2.关闭Broker sh bin/mqshutdown broker
三、安装 RocketMQ-Dashboard
1、将代码下载下来,下载地址
https://github.com/apache/rocketmq-dashboard
2、解压之后,执行 mvn 进行打包;
mvn clean package -Dmaven.test.skip=true
3、运行 jar 包
nohup java -jar rocketmq-dashboard-1.0.0.jar --server.port=8080 --rocketmq.config.namesrvAddr=localhost:9876 &
4、访问管理界面
http://192.168.172.20:8080
四、集群搭建
Broker 的配置说明:
# rocketmq-name服务地址,多个地址用;分开,不配置默认为localhost:9876 namesrvAddr = 192.168.241.198:9876;192.168.241.199:9876
# 可以配置成自己需要的名称 brokerClusterName = DefaultCluster
# 搭建集群的时候 Master 和 Slave 的 brokerName 要配置的一样 brokerName = broker-b
# brokeId=0,表示为 Master 节点;所有的 非0 节点都为 Slave brokerId = 0
# 每天的凌晨 4 点删除消息 deleteWhen = 04
# 数据存在磁盘上最多 48 小时 fileReservedTime = 48
# 当前节点角色;消息同步到Slave之后再响应 brokerRole = SYNC_MASTER
# 刷盘的策略;
# 同步刷盘:消息写到缓冲区之后,立刻通知线程去进行刷盘,刷盘成功之后再响应成功;
# 异步刷盘,消息先写到缓冲区之后,缓冲区的大小到达指定的保准之后去通知线程进行刷盘;异步刷盘可能造成数据丢失; flushDiskType = ASYNC_FLUSH
# 自动创建 topic autoCreateTopicEnable=true
# broker通信端口,默认端口 listenPort=10911 storePathRootDir=/root/rocketmq/store-m storePathCommitLog=/root/rocketmq/store-m/store/commitlog
cd conf目录 cp broker.conf broker-m.conf cp broker.conf broker-s.conf
#rocketmq-name服务地址,多个地址用;分开,不配置默认为localhost:9876 namesrvAddr = 192.168.241.198:9876;192.168.241.199:9876 #可以配置成自己需要的名称 brokerClusterName = DefaultCluster brokerName = broker-b # 0表示主节点 brokerId = 0 deleteWhen = 04 fileReservedTime = 48 #当前节点角色 brokerRole = SYNC_MASTER flushDiskType = ASYNC_FLUSH autoCreateTopicEnable=true #broker通信端口,默认端口 listenPort=10911 storePathRootDir=/root/rocketmq/store-m storePathCommitLog=/root/rocketmq/store-m/store/commitlog
#rocketmq-name 服务地址,多个地址用;分开,不配置默认为localhost:9876 namesrvAddr = 192.168.241.198:9876;192.168.241.199:9876 #可以配置成自己需要的名称 brokerClusterName = DefaultCluster brokerName = broker-b # 非0表示从节点 brokerId = 1 deleteWhen = 04 fileReservedTime = 48 #当前节点角色 brokerRole = SLAVE flushDiskType = ASYNC_FLUSH autoCreateTopicEnable=true #broker通信端口 listenPort=10811 storePathRootDir=/root/rocketmq/store-s storePathCommitLog=/root/rocketmq/store-s/store/commitlog
nohup sh mqnamesrv &
cd 到rocketmq根目录执行命令 nohup sh bin/mqbroker -c conf/broker-m.conf &
cd 到rocketmq根目录执行命令 nohup sh bin/mqbroker -c conf/broker-s.conf &
namesrvAddr = 192.168.241.198:9876;192.168.241.199:9876 #可以配置成自己需要的名称 brokerClusterName = DefaultCluster brokerName = broker-a brokerId = 0 deleteWhen = 04 fileReservedTime = 48 brokerRole = SYNC_MASTER flushDiskType = ASYNC_FLUSH autoCreateTopicEnable=true listenPort=10911 storePathRootDir=/root/rocketmq/store-m storePathCommitLog=/root/rocketmq/store-m/store/commitlog
namesrvAddr = 192.168.241.198:9876;192.168.241.199:9876 #可以配置成自己需要的名称 brokerClusterName = DefaultCluster brokerName = broker-a brokerId = 1 deleteWhen = 04 fileReservedTime = 48 brokerRole = SLAVE flushDiskType = ASYNC_FLUSH autoCreateTopicEnable=true listenPort=10811 storePathRootDir=/root/rocketmq/store-s storePathCommitLog=/root/rocketmq/store-s/store/commitlog
启动mqnamesrv 与 mqbroker 启动流程同上。
# 查看集群监控状态 sh mqadmin clusterlist -n 192.168.241.198:9876
export NAMESRV_ADDR=192.168.241.198:9876;192.168.241.199:9876 测试发送端 > sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer 测试消费端 > sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
配置说明
1.namesrvAddr NameServer地址,可以配置多个,用逗号分隔; 2.brokerClusterName 所属集群名称,如果节点较多可以配置多个 3.brokerName broker名称,master和slave使用相同的名称,表明他们的主从关系 4.brokerId 0表示Master,大于0表示不同的slave 5.deleteWhen 表示几点做消息删除动作,默认是凌晨4点 6.fileReservedTime 在磁盘上保留消息的时长,单位是小时 7.brokerRole 有三个值:SYNC_MASTER,ASYNC_MASTER,SLAVE;同步和异步表示Master和Slave之间同步数据的机制; 8.flushDiskType 刷盘策略,取值为:ASYNC_FLUSH,SYNC_FLUSH表示同步刷盘和异步刷盘;SYNC_FLUSH消息写入磁盘后才返回成功状态,ASYNC_FLUSH不需要; 9.listenPort 启动监听的端口号 10.storePathRootDir 存储消息的根目录