一、单机部署
我们会部署一套 RocketMQ 最小化的单机环境,包括一个 RocketMQ Namesrv 和 Broker 服务。部署完成之后,我们会测试消息的发送与消费。下面,让我们逐步开始。
1.1 前置条件
需要安装如下软件:
- JDK 8+
- Maven 3.2.X+
- 64位操作系统,建议使用 Linux / Unix / Mac
因为我们准备直接编译 RocketMQ 源码,构建出 RocketMQ 软件包。
1.2 下载源码
打开 RocketMQ release_notes 页面,我们可以看到 RocketMQ 所有的发布版本。这里,我们选择最新的 RocketMQ 4.7.1 版本。点击进入该版本的发布页面后,我们可以看到两种发布版本:
一般情况下,我们可以直接使用 Binary 版本,它是 RocketMQ 已经编译好,可以直接使用的 RocketMQ 软件包。
这里,我们想编译一次 RocketMQ 源码,所以使用 Source 版本。下面,我们开始下载 RocketMQ 4.7.1 Source 源码。命令行操作如下:
# 下载
$ wget http://mirror.bit.edu.cn/apache/rocketmq/4.7.1/rocketmq-all-4.7.1-source-release.zip
# 解压
$ unzip rocketmq-all-4.7.1-source-release.zip
1.2 编译源码
使用 Maven 编译 RocketMQ 源码。命令行操作如下:
# 进入 RocketMQ 源码目录
$ cd rocketmq-all-4.7.1-source-release
# Maven 编译 RocketMQ ,并跳过测试。耐心等待...
$ mvn -Prelease-all -DskipTests clean install -U
编译完成,会看到成功提示:
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for Apache RocketMQ 4.7.1 4.7.1:
[INFO]
[INFO] Apache RocketMQ 4.7.1 .............................. SUCCESS [02:38 min]
[INFO] rocketmq-logging 4.7.1 ............................. SUCCESS [ 14.979 s]
[INFO] rocketmq-remoting 4.7.1 ............................ SUCCESS [ 4.222 s]
[INFO] rocketmq-common 4.7.1 .............................. SUCCESS [ 5.097 s]
[INFO] rocketmq-client 4.7.1 .............................. SUCCESS [ 7.221 s]
[INFO] rocketmq-store 4.7.1 ............................... SUCCESS [ 4.552 s]
[INFO] rocketmq-srvutil 4.7.1 ............................. SUCCESS [ 0.467 s]
[INFO] rocketmq-filter 4.7.1 .............................. SUCCESS [ 2.131 s]
[INFO] rocketmq-acl 4.7.1 ................................. SUCCESS [ 2.037 s]
[INFO] rocketmq-broker 4.7.1 .............................. SUCCESS [ 3.209 s]
[INFO] rocketmq-tools 4.7.1 ............................... SUCCESS [ 2.039 s]
[INFO] rocketmq-namesrv 4.7.1 ............................. SUCCESS [ 0.840 s]
[INFO] rocketmq-logappender 4.7.1 ......................... SUCCESS [ 1.340 s]
[INFO] rocketmq-openmessaging 4.7.1 ....................... SUCCESS [ 1.661 s]
[INFO] rocketmq-example 4.7.1 ............................. SUCCESS [ 0.982 s]
[INFO] rocketmq-test 4.7.1 ................................ SUCCESS [ 3.463 s]
[INFO] rocketmq-distribution 4.7.1 ........................ SUCCESS [01:25 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 04:59 min
[INFO] Finished at: 2020-08-03T15:59:58+08:00
[INFO] ------------------------------------------------------------------------
在我们进入 distribution 目录下,就可以看到 RocketMQ 的发布包了。命令行操作如下:
# 进入 distribution 目录下
$ cd distribution/target/rocketmq-4.7.1/rocketmq-4.7.1
# 当前目录为:/root/data/rocketMQ/rocketmq-all-4.7.1-source-release/distribution/target/rocketmq-4.7.1/rocketmq-4.7.1。
# 打印目录
$ ls
drwxr-xr-x 2 root root 4096 Aug 3 15:59 benchmark # 性能基准测试
drwxrwxr-x 3 root root 4096 Jun 24 14:05 bin # 执行脚本
drwxrwxr-x 6 root root 4096 Jun 24 14:05 conf # 配置文件
drwxr-xr-x 2 root root 4096 Aug 3 15:59 lib # RocketMQ jar 包
-rw-rw-r-- 1 root root 17336 Jun 24 14:05 LICENSE
-rw-rw-r-- 1 root root 1338 Jun 24 14:05 NOTICE
-rw-rw-r-- 1 root root 5069 Jun 24 14:05 README.md
1.3 启动 Namesrv
启动一个 RocketMQ Namesrv 服务。命令行操作如下:
$ nohup sh bin/mqnamesrv &
启动完成后,查看日志。
# 查看 Namesrv 日志。
$ tail -f ~/logs/rocketmqlogs/namesrv.log
2020-08-03 16:03:32 INFO main - The Name Server boot success. serializeType=JSON
默认情况下,Namesrv 日志文件所在地址为
~/logs/rocketmqlogs/namesrv.log
。如果想要自定义,可以通过conf/logback_namesrv.xml
配置文件来进行修改。
1.4 启动 Broker
在 conf
目录下,RocketMQ 提供了多种 Broker 的配置文件:
-
broker.conf
:单主,异步刷盘。 -
2m/
:双主,异步刷盘。 -
2m-2s-async/
:两主两从,异步复制,异步刷盘。建议方式:[搭建文档]。(https://www.cnblogs.com/powerx/p/13345054.html) -
2m-2s-sync/
:两主两从,同步复制,异步刷盘。 -
dledger/
:Dledger 集群,至少三节点。
这里,我们只启动一个 RocketMQ Broker 服务,所以使用 broker.conf
配置文件。命令行操作如下:
$ nohup sh bin/mqbroker -c conf/broker.conf -n 127.0.0.1:9876 &
- 通过 -c 参数,配置读取的主 Broker 配置。
- 通过 -n 参数,设置 RocketMQ Namesrv 地址。
启动完成后,查看日志:
$ tail -f ~/logs/rocketmqlogs/broker.log
2020-08-03 16:20:35 INFO main - The broker[broker-a, 172.19.152.208:10911] boot success. serializeType=JSON and name server is 127.0.0.1:9876
注意记下
172.19.152.208:10911
后面会使用这个broker地址。
如果提示找不到上面的日志文件,应该是没启动成功。
先看这个日志:
$ tail -f nohup.out
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 8589934592 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /root/data/rocketMQ/rocketmq-all-4.7.1-source-release/distribution/target/rocketmq-4.7.1/rocketmq-4.7.1/hs_err_pid17566.log
应该是内存不够,RocketMQ默认用8g内存,如果你服务器的内存比较小,可以修改下bin/runbroker.sh
脚本,将 Broker JVM 内存调小。如:JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g"
。
再次启动broker,可以正常启动。
默认情况下,Broker 日志文件所在地址为
~/logs/rocketmqlogs/broker.log
。如果想要自定义,可以通过conf/logback_broker.xml
配置文件来进行修改。
至此,我们已经完成了 RocketMQ 单机部署。下面,我们开始进行下消息的发送和消费的测试。
1.5 测试发送消息
在发送/接收消息之前,我们需要告诉客户名称服务器的位置。RocketMQ 提供了多种方法来实现这一点。为了简单起见,我们使用环境变量NAMESRV_ADDR
。通过使用 bin/tools.sh
工具类,实现测试发送消息。命令行操作如下:
# 设置 Namesrv 服务器的地址
export NAMESRV_ADDR=127.0.0.1:9876
# 执行生产者 Producer 发送测试消息
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
如果发送成功,我们会看到大量成功的发送日志。
......
SendResult [sendStatus=SEND_OK, msgId=AC1398D0491955F963020DDB5BF503E6, offsetMsgId=AC1398D000002A9F00000000000316F4, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=2], queueOffset=249]
SendResult [sendStatus=SEND_OK, msgId=AC1398D0491955F963020DDB5BF603E7, offsetMsgId=AC1398D000002A9F00000000000317BF, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=3], queueOffset=249]
发送结果为sendStatus=SEND_OK
状态,说明消息都发送成功了。
1.6 测试消费消息
通过使用bin/tools.sh
工具类,实现测试消费消息。命令行操作如下:
# 设置 Namesrv 服务器的地址
export NAMESRV_ADDR=127.0.0.1:9876
# 执行消费者 Consumer 消费测试消息
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
如果消费成功,我们会看到大量成功的消费日志。
ConsumeMessageThread_18 Receive New Messages: [MessageExt [brokerName=broker-a, queueId=3, storeSize=203, queueOffset=120, sysFlag=0, bornTimestamp=1596443679060, bornHost=/172.19.152.208:58168, storeTimestamp=1596443679060, storeHost=/172.19.152.208:10911, msgId=AC1398D000002A9F0000000000017E93, commitLogOffset=97939, bodyCRC=1461711895, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='TopicTest', flag=0, properties={MIN_OFFSET=0, MAX_OFFSET=250, CONSUME_START_TIME=1596443856856, UNIQ_KEY=AC1398D0491955F963020DDB595401E3, CLUSTER=DefaultCluster, WAIT=true, TAGS=TagA}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107, 101, 116, 77, 81, 32, 52, 56, 51], transactionId='null'}]]
ConsumeMessageThread_20 Receive New Messages: [MessageExt [brokerName=broker-a, queueId=0, storeSize=203, queueOffset=229, sysFlag=0, bornTimestamp=1596443679665, bornHost=/172.19.152.208:58168, storeTimestamp=1596443679666, storeHost=/172.19.152.208:10911, msgId=AC1398D000002A9F000000000002D5EE, commitLogOffset=185838, bodyCRC=2121214082, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='TopicTest', flag=0, properties={MIN_OFFSET=0, MAX_OFFSET=250, CONSUME_START_TIME=1596443857406, UNIQ_KEY=AC1398D0491955F963020DDB5BB10394, CLUSTER=DefaultCluster, WAIT=true, TAGS=TagA}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107, 101, 116, 77, 81, 32, 57, 49, 54], transactionId='null'}]]
通过ConsumeMessageThread_18
和ConsumeMessageThread_20
线程名,我们可以看出,目前是进行并发消费消息。
1.7关闭服务器
# sh bin/mqshutdown broker //停止 broker
# sh bin/mqshutdown namesrv //停止 nameserver
关闭成功后如下:
# ./bin/mqshutdown broker
The mqbroker(17872) is running...
Send shutdown request to mqbroker(17872) OK
# ./bin/mqshutdown namesrv
The mqnamesrv(16946) is running...
Send shutdown request to mqnamesrv(16946) OK
1.8 常用命令
上面几个启动和关闭 name server 和 broker 的就不再说了,先进入bin目录:# cd bin
。
- 查看集群情况
./mqadmin clusterList -n 127.0.0.1:9876
- 查看 broker 状态
./mqadmin brokerStatus -n 127.0.0.1:9876 -b 172.19.152.208:10911
(注意换成你的 broker 地址) - 查看 topic 列表
./mqadmin topicList -n 127.0.0.1:9876
- 查看 topic 状态
./mqadmin topicStatus -n 127.0.0.1:9876 -t MyTopic
(换成你想查询的 topic) - 查看 topic 路由
./mqadmin topicRoute -n 127.0.0.1:9876 -t MyTopic
二、集群部署
在生产环境下,必须搭建 RocketMQ 高可用集群,一般 RocketMQ 的集群部署方案推荐如下:
- 如果对高性能有比较强的诉求,使用两主两从,异步复制,异步刷盘。
- 如果对可靠性有比较强的诉求,建议使用 Dledger 集群,至少三节点。
2.1. Producer
1、Producer 自身在应用中,所以无需考虑高可用。
2、Producer 配置多个 Namesrv 列表,从而保证 Producer 和 Namesrv 的连接高可用。并且,会从 Namesrv 定时拉取最新的 Topic 信息。
3、Producer 会和所有 Consumer 直连,在发送消息时,会选择一个 Broker 进行发送。如果发送失败,则会使用另外一个 Broker 。
4、Producer 会定时向 Broker 心跳,证明其存活。而 Broker 会定时检测,判断是否有 Producer 异常下线。
2.2. Consumer
1、Consumer 需要部署多个节点,以保证 Consumer 自身的高可用。当相同消费者分组中有新的 Consumer 上线,或者老的 Consumer 下线,会重新分配 Topic 的 Queue 到目前消费分组的 Consumer 们。
2、Consumer 配置多个 Namesrv 列表,从而保证 Consumer 和 Namesrv 的连接高可用。并且,会从 Consumer 定时拉取最新的 Topic 信息。
3、Consumer 会和所有 Broker 直连,消费相应分配到的 Queue 的消息。如果消费失败,则会发回消息到 Broker 中。
4、Consumer 会定时向 Broker 心跳,证明其存活。而 Broker 会定时检测,判断是否有 Consumer 异常下线。
2.3. Namesrv
1、Namesrv 需要部署多个节点,以保证 Namesrv 的高可用。
2、Namesrv 本身是无状态,不产生数据的存储,是通过 Broker 心跳将 Topic 信息同步到 Namesrv 中。
3、多个 Namesrv 之间不会有数据的同步,是通过 Broker 向多个 Namesrv 多写。
2.4. Broker
1、多个 Broker 可以形成一个 Broker 分组。每个 Broker 分组存在一个 Master 和多个 Slave 节点。
Master 节点,可提供读和写功能。Slave 节点,可提供读功能。
Master 节点会不断发送新的 CommitLog 给 Slave节点。Slave 节点不断上报本地的 CommitLog 已经同步到的位置给 Master 节点。
Slave 节点会从 Master 节点拉取消费进度、Topic 配置等等。
2、多个 Broker 分组,形成 Broker 集群。
Broker 集群和集群之间,不存在通信与数据同步。
3、Broker 可以配置同步刷盘或异步刷盘,根据消息的持久化的可靠性来配置。
三、Web Console 控制台
在 RocketMQ 拓展项目(rocketmq-externals) 中,包含了 RocketMQ Console 项目,是 RocketMQ 的图形化管理控制台,提供 Broker 集群信息查看,Topic 管理,Producer、Consumer 信息展示,消息查询等等常用功能。
虽然说,我们也可以使用 RocketMQ 提供的 CLI Admin Tool 工具,实现上述的查询与管理的功能,但是命令行的方式对操作人员的要求稍高一些。当然,在 RocketMQ Console 无法满足我们更精细化的管理的需求的时候,我们还是会使用 CLI Admin Tool 工具。
下面,让我们来搭建一个 RocketMQ Console 控制台。
3.1 克隆代码
将 rocketmq-externals 仓库的代码,克隆到本地。操作流程如下:
# 克隆代码
$ git clone https://github.com/apache/rocketmq-externals.git
#国内仓库
$ git clone https://gitee.com/mirrors/RocketMQ-Externals.git
# 进入 Console 目录
$ cd rocketmq-console
3.2 配置文件
如果胖友需要自定义 RocketMQ Console 的配置,可以进入该项目下的 src/main/resources/ 目录下,进行相应的配置文件修改。例如说,设置 RocketMQ Namesrv 地址,开启 RocketMQ Console 的登录访问。
这里,我们修改src/main/resources/application.properties
配置文件,通过设置 rocketmq.config.namesrvAddr=127.0.0.1:9876
配置项,设置 RocketMQ Namesrv 的地址。
3..3 编译源码
使用 Maven 编译 RocketMQ Console 源码。命令行操作如下:
# 编译
$ mvn clean package -Dmaven.test.skip=true
看到如下信息代表编译成功:
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:10 min
[INFO] Finished at: 2020-08-03T17:04:54+08:00
[INFO] ------------------------------------------------------------------------
3.4 启动控制台
由于是springboot2.2.2项目,直接以 jar 的方式,启动控制台。注意,控制台使用 8080 端口。命令行操作如下:
$ nohup java -jar target/rocketmq-console-ng-2.0.0.jar &
启动完成后,查看日志。
$ tail -f nohup.out
[2020-08-03 17:08:46.787] INFO Starting ProtocolHandler ["http-nio-0.0.0.0-8080"]
[2020-08-03 17:08:46.818] INFO Tomcat started on port(s): 8080 (http) with context path ''
[2020-08-03 17:08:46.821] INFO Started App in 6.2 seconds (JVM running for 6.903)
当看到如上日志,说明 Console 控制台启动完成。
3.5 简单使用
使用浏览器,访问 http://127.0.0.1:8080/ 地址,我们就可以看到 RocketMQ Console 的界面。