RocketMQ入门案例【面试+工作】

227 阅读13分钟
原文链接: www.jianshu.com

0 RocketMQ简介

0.1 介绍

RocketMQ是一个消息中间件。消息中间件中有两个角色:消息生产者和消息消费者。RocketMQ里同样有这两个概念,消息生产者负责创建消息并发送到RocketMQ服务器,RocketMQ服务器会将消息持久化到磁盘,消息消费者从RocketMQ服务器拉取消息并提交给应用消费。

0.2 特点

RocketMQ是一款分布式、队列模型的消息中间件,具有以下特点:

支持严格的消息顺序

支持Topic与Queue两种模式

亿级消息堆积能力

比较友好的分布式特性

同时支持Push与Pull方式消费消息

历经多次天猫双十一海量消息考验

0.3 部署结构

上图所示为RocketMQ的部署结构,图中Meta字样为RocketMQ早期代号。

1 RocketMQ 消息队列单机部署

1.1 系统配置环境

主机:Linux

内存:8G

硬盘:250G

CPU:4核

1.2 需要用到的软件包和文档

目前在Github上可下载最新的安装包alibaba-rocketmq-3.2.6.tar

下载地址:https://github.com/alibaba/RocketMQ

历史版本说明文档:Metaq原理与应用.docx 

下载地址:

http://gd-rus-public.cn-hangzhou.oss-pub.aliyun-inc.com/attachment/201604/08/20160408140549/20160408Metaq%E5%8E%9F%E7%90%86%E4%B8%8E%E5%BA%94%E7%94%A8.docx

备注:RocketMQ早起在淘宝内部叫Metaq,去年改名为RocketMQ,不过该文档是针对历史版本的Metaq,仅供参考和熟悉一些概念。

1.3 服务器java环境

1.4 rocketmq服务端安装

解压alibaba-rocketmq-3.2.6.tar

配置rocketmq的环境变量,在/etc/profile最后添加

使rocketmq的环境变量生效

给下列命令可执行权限

新建日志文件夹

启动nameserver

查看启动状态

验证nameserver是否启动

启动broker,在启动borker之前需要指定nameserver地址,其中10.125.1.186为所在服务器IP

验证mqbroker是否启动

最后配置防火墙

nameserver端口为9876

broker端口为10911

关闭nameserver broker执行的命令

关闭nameserver

关闭broker

安装成功显示结果:

2 java客户端使用RocketMQ 消息队列

2.1 依赖配置

2.2 创建生产者

用来获取一个单例的生产者。

2.3 创建消费者

用来获取一个单例的消费者。消费者类似于直接操作数据库的对象,比如生产者下了订单订火车票,消费者就一直监听,有订单消息过来了,就去执行下订单操作。

2.4 创建生产和消费服务

2.5 测试效果

2.5.1 生产100个消息

2.5.2 消费100个消息

3 总结

本文仅供初学者学习如何使用RocketMQ,目前仅仅是单机配置,还没有涉及到集群等配置,后续会不断学习和记录

核心原理

1.1. 数据结构

(1)所有数据单独储存到commit Log ,完全顺序写,随机读

(2)对最终用户展现的队列实际只储存消息在Commit Log 的位置信息,并且串行方式刷盘

(3)按照MessageId查询消息

(4)根据查询的key的hashcode%slotNum得到具体的槽位置

(5)根据slotValue(slot对应位置的值)查找到索引项列表的最后一项

(6)遍历索引项列表返回查询时间范围内的结果集

1.2. 刷盘策略

rocketmq中的所有消息都是持久化的,先写入系统pagecache,然后刷盘,可以保证内存与磁盘都有一份数据,访问时,可以直接从内存读取

使用简单的符号标识不同的标题,将某些文字标记为粗体或者斜体,创建一个链接等,详细语法参考帮助?。

本编辑器支持Markdown Extra,  扩展了很多好用的功能。具体请参考[Github][2].

1.3. 内存机制

1.4. 工作模式

2. 环境安装

2.1. JAVA环境安装

安装

环境变量

2.2. RocketMq安装

3. 测试网络拓扑

因为手里没有其他服务器,105那台缺少一个slave,在同步双写模式下,发送消息会返回SLAVE_NOT_AVAILABLE,不过消息已经发送成功,只是slave没有写成功。

4. 启停操作

启动nameserver

停止nameServer

启动broker(单master)(多master,多master+slave)对应的(异步复制,同步双写)

停止broker

5. 运维指令

查看集群情况

查看broker状态

查看topic列表

查看topic状态

查看topic路由

6.宕机实验

7.控制台使用

RocketMQ 提供有控制台及一系列控制台命令,用于管理员对主题,集群,broker 等信息的管理;

登录控制台

首先进入RocketMQ 工程,进入/RocketMQ/bin

在该目录下有个mqadmin 脚本

查看帮助

在mqadmin 下可以查看有哪些命令

sh mqadmin

查看具体命令的使用

sh mqadmin help 命令名称

例如,查看updateTopic 的使用

sh mqadmin help updateTopic

8.Broker集群部署

推荐的几种 Broker 集群部署方式,这里的Slave 不可写,但可读,类似与 Mysql 主备方式。

1.单个 Master

这种方式风险较大,一旦Broker 重启或者宕机时,会导致整个服务不可用,不建议线上环境使用。

2.多 Master 模式

一个集群无 Slave,全是 Master,例如 2 个 Master 或者 3 个 Master

优点:配置简单,单个Master 宕机或重启维护对应用无影响,在磁盘配置为 RAID10 时,即使机器宕机不可恢复情况下,由与 RAID10 磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢)。性能最高。

缺点:单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到受到影响。

###  先启动 NameServer,例如机器 IP 为:192.168.1.1:9876

nohup sh mqnamesrv &

###  在机器 A,启动第一个 Master

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-noslave/broker-a.properties &

###  在机器 B,启动第二个 Master

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-noslave/broker-b.properties &

3.多 Master 多 Slave 模式,异步复制

每个 Master 配置一个 Slave,有多对Master-Slave,HA 采用异步复制方式,主备有短暂消息延迟,毫秒级。

优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,因为 Master 宕机后,消费者仍然可以从 Slave 消费,此过程对应用透明。不需要人工干预。性能同多 Master 模式几乎一样。

缺点:Master 宕机,磁盘损坏情况,会丢失少量消息。

###  先启动 NameServer,例如机器 IP 为:192.168.1.1:9876

nohup sh mqnamesrv &

###  在机器 A,启动第一个 Master

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-2s-async/broker-a.properties &

###  在机器 B,启动第二个 Master

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-2s-async/broker-b.properties &

###  在机器 C,启动第一个 Slave

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-2s-async/broker-a-s.properties &

###  在机器 D,启动第二个 Slave

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-2s-async/broker-b-s.properties &

4.  多 Master 多 Slave 模式,同步双写

每个 Master 配置一个 Slave,有多对Master-Slave,HA 采用同步双写方式,主备都写成功,向应用返回成功。

优点:数据与服务都无单点,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高

缺点:性能比异步复制模式略低,大约低 10%左右,发送单个消息的 RT 会略高。目前主宕机后,备机不能自动切换为主机,后续会支持自动切换功能。

###  先启动 NameServer,例如机器 IP 为:192.168.1.1:9876

nohup sh mqnamesrv &

###  在机器 A,启动第一个 Master

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-2s-sync/broker-a.properties &

###  在机器 B,启动第二个 Master

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-2s-sync/broker-b.properties &

###  在机器 C,启动第一个 Slave

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-2s-sync/broker-a-s.properties &

###  在机器 D,启动第二个 Slave

nohup sh mqbroker -n 192.168.1.1:9876 -c$ROCKETMQ_HOME/conf/2m-2s-sync/broker-b-s.properties &

以上 Broker 与 Slave 配对是通过指定相同的brokerName 参数来配对,Master 的 BrokerId 必须是 0,Slave 的BrokerId 必须是大与 0 的数。另外一个 Master 下面可以挂载多个 Slave,同一 Master 下的多个 Slave 通过指定不同的 BrokerId 来区分。

$ROCKETMQ_HOST 指的 RocketMQ 安装目录,需要用户自己设置此环境变量

9.详细命令

9.1. 创建Topic

指令 

updateTopic 

类路径 

com.alibaba.rocketmq.tools.command.topic.UpdateTopicSubCommand

参数是否必填说明

-b如果-c为空,则必填broker 地址,表示topic 建在该broker

-c如果-b为空,则必填cluster 名称,表示topic 建在该集群(集群可通过clusterList 查询)

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

-p否 指定新topic 的权限限制( W|R|WR )

-r 否可读队列数(默认为8)

-w否可写队列数(默认为8)

-t是opic 名称(名称只能使用字符 ^[a-zA-Z0-9_-]+$ )

9.2. 删除Topic

指令 

deleteTopic 

类路径 

com.alibaba.rocketmq.tools.command.topic.DeleteTopicSubCommand

参数 是否必填 说明

-c是cluster 名称,表示删除某集群下的某个topic (集群可通过clusterList 查询)

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;…

-t是topic 名称(名称只能使用字符 ^[a-zA-Z0-9_-]+$ )

9.3. 创建(修订)订阅组

指令 

updateSubGroup 

类路径 

com.alibaba.rocketmq.tools.command.consumer.UpdateSubGroupSubCommand

参数是否必填说明

-b如果 –c 为空,则必填broker 地址,表示订阅组建在该broker

-c如果 –b 为空,则必填cluster名称,表示topic 建在该集群(集群可通过clusterList查询)

-d否 是否容许广播方式消费

-g是 订阅组名

-i否从哪个broker 开始消费

-m否是否容许从队列的最小位置开始消费,默认会设置为false

-q否消费失败的消息放到一个重试队列,每个订阅组配置几个重试队列

-r 否 重试消费最大次数,超过则投递到死信队列,不再投递,并报警

-s否消费功能是否开启

-w 否发现消息堆积后,将Consumer 的消费请求重定向到另外一台Slave 机器

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.4. 删除订阅组配置

指令 

deleteSubGroup 

类路径 

com.alibaba.rocketmq.tools.command.consumer.DeleteSubscriptionGroupCommand

参数是否必填说明

-b 如果–c 为空,则必填broker 地址,表示订阅组建在该broker

-c 如果–b 为空,则必填cluster 名称,表示topic建在该集群(集群可通过clusterList查询)

-g是订阅组名

-h否打印帮助

-n 是nameserve 服务地址列表,格式ip:port;ip:port;...

9.5. 更新Broker 配置文件

指令 

updateBrokerConfig

类路径

com.alibaba.rocketmq.tools.command.broker.UpdateBrokerConfigSubCommand

参数是否必填说明

-b 如果–c为空,则必填broker 地址,表示订阅组建在该broker

-c 如果–b 为空,则必填cluster名称,表示topic 建在该集群(集群可通过clusterList查询)

-k 是 key 值

-v否value 值

-h否打印帮助

-n 是nameserve 服务地址列表,格式ip:port;ip:port;...

9.6. 查看Topic 列表信息

指令 

topicList 

类路径 

com.alibaba.rocketmq.tools.command.broker.UpdateBrokerConfigSubCommand

参数是否必填说明

-h否打印帮助

-n 是nameserve 服务地址列表,格式ip:port;ip:port;...

9.7. 查看Topic 路由信息

指令 

topicRoute 

类路径 

com.alibaba.rocketmq.tools.command.topic.TopicRouteSubCommand

参数是否必填说明

-t是topic 名称

-h否打印帮助

-n 是nameserve 服务地址列表,格式ip:port;ip:port;...

9.8. 查看Topic 统计信息

指令 

topicStats 

类路径

com.alibaba.rocketmq.tools.command.topic.TopicStatsSubCommand

参数是否必填说明

-t是topic 名称

-h否打印帮助

-n 是nameserve 服务地址列表,格式ip:port;ip:port;...

9.9. 查看Broker 统计信息

指令 

brokerStats 

类路径

com.alibaba.rocketmq.tools.command.broker.BrokerStatsSubCommanD

参数是否必填说明

-b是 broker 地址

-h否打印帮助

-n 是nameserve 服务地址列表,格式ip:port;ip:port;...

9.10. 根据消息ID 查询消息

指令 

queryMsgById 

类路径

com.alibaba.rocketmq.tools.command.message.QueryMsgByIdSubCommand

参数是否必填说明

-i是 消息id

-h否打印帮助

-n 是nameserve 服务地址列表,格式ip:port;ip:port;...

9.11. 根据消息Key 查询消息

指令 

queryMsgByKey 

类路径

com.alibaba.rocketmq.tools.command.message.QueryMsgByKeySubCommand

参数是否必填说明

-f否被查询消息的截止时间

-k是msgKey

-t是topic 名称

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.12. 根据Offset 查询消息

指令 

queryMsgByOffset

类路径

com.alibaba.rocketmq.tools.command.message.QueryMsgByOffsetSubCommand

参数是否必填说明

-b 是Broker 名称,表示订阅组建在该broker(这里需要注意填写的是broker 的名称,不是broker 的地址,broker名称可以在clusterList 查到

-i是query 队列id

-o是offset 值

-t是topic 名称

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.13. 查询Producer 的网络连接

该命令只打印当前与cluster 连接的producer 网络连接信息

指令 

producerConnection

类路径

com.alibaba.rocketmq.tools.command.connection.ProducerConnectionSubCommand

参数是否必填说明

-g是生产者所属组名

-t是topic 名称

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.14. 查询Consumer 的网络连接

该命令只打印当前与cluster 连接的consumer 网络连接信息

指令 

consumerConnection

类路径

com.alibaba.rocketmq.tools.command.connection.ConsumerConnectionSubCommand

参数是否必填说明

-g是消费者所属组名

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.15. 查看订阅组消费状态

指令 

consumerProgress

类路径

com.alibaba.rocketmq.tools.command.consumer.ConsumerProgressSubCommand

参数是否必填说明

-g是消费者所属组名

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.16. 查看集群消息

指令 

clusterList 

类路径

com.alibaba.rocketmq.tools.command.cluster.ClusterListSubCommand

参数是否必填说明

-m否打印更多信息

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.17. 添加(更新)KV 配置信息

指令 

updateKvConfig 

类路径

com.alibaba.rocketmq.tools.command.namesrv.UpdateKvConfigCommand

参数是否必填说明

-k是key 值

-v是value 值

-s是Namespace 值

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.18. 删除KV 配置信息

指令 

deleteKvConfig 

类路径

com.alibaba.rocketmq.tools.command.namesrv.DeleteKvConfigCommand

参数是否必填说明

-k是key 值

-s是Namespace 值

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.19. 添加(更新)Project group 配置信息

指令 updateProjectGroup 

类路径 com.alibaba.rocketmq.tools.command.namesrv.UpdateProjectGroupCommand

参数是否必填说明

-p是project group 名

-i否服务器ip

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.20. 删除Project group 配置信息

指令 

deleteProjectGroup

类路径

com.alibaba.rocketmq.tools.command.namesrv.DeleteProjectGroupCommand

参数是否必填说明

-p是project group 名

-i否服务器ip

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.21. 取得Project group 配置信息

指令 

getProjectGroup

类路径

com.alibaba.rocketmq.tools.command.namesrv.GetProjectGroupCommand

参数是否必填说明

-p是project group 名

-i否服务器ip

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;..

9.22. 设置消费进度

根据时间来设置消费进度,设置之前要关闭这个订阅组的所有consumer,设置完再启动,方可生效

指令 

resetOffsetByTime

类路径

com.alibaba.rocketmq.tools.command.offset.ResetOffsetByTimeSubCommand

参数是否必填说明

-f否通过时间戳强制回滚(true|false),默认为true

-s是时间戳

-g是消费者所属组名

-t是topic 名称

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.23. 清除特定Broker权限

指令 

wipeWritePerm 

类路径

com.alibaba.rocketmq.tools.command.namesrv.WipeWritePermSubCommand

参数是否必填说明

-b是broker 地址

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...

9.24. 获取Consumer消费进度

该命令只打印当前与cluster 连接的consumer 的消费进度

指令 

getConsumerStatus

类路径 

com.alibaba.rocketmq.tools.command.offset.GetConsumerStatusCommand

参数是否必填说明

-g是消费者所属组名

-t是查询主题

-i否Consumer 客户端ip

-h否打印帮助

-n是nameserve 服务地址列表,格式ip:port;ip:port;...