RocketMQ 4.7.1 单机安装

博文目录


RocketMQ

RocketMQ是阿里巴巴开源的一个消息中间件,在阿里内部历经了双十一等很多高并发场景的考验,能够处理亿万级别的消息。2016年开源后捐赠给Apache,现在是Apache的一个顶级项目。

​ 目前RocketMQ在阿里云上有一个购买即可用的商业版本,商业版本集成了阿里内部一些更深层次的功能及运维定制。我们这里学习的是Apache的开源版本。开源版本相对于阿里云上的商业版本,功能上略有缺失,但是大体上功能是一样的。

官网
GitHub
官方中文文档
rocketmq-all-4.7.1-source-release.zip
rocketmq-all-4.7.1-bin-release.zip
rocketmq-externals

当前官网最新版本是4.7.1, 下载 rocketmq-all-4.7.1-bin-release.zip

安装

RocketMQ需要JDK环境

Linux Oracle JDK 下载 安装 配置 使用

本地解压 rocketmq-all-4.7.1-bin-release.zip, 然后上传到 linux, 并重命名为 rocketmq-4.7.1

把rocketmq的bin目录也配置到环境变量当中, 在 /root/.bashrc 文件内添加如下内容, source /root/.bashrc 刷新配置

export JAVA_HOME=/mrathena/application/jdk-1.8.0.202
export ROCKETMQ_HOME=/application/rocketmq-4.7.1
export PATH=$JAVA_HOME/bin:$ROCKETMQ_HOME/bin:$PATH
export CLASSPARH=.:$JAVA_HOME/lib

这个ROCKETMQ_HOME的环境变量是必须要单独配置的,如果不配置的话,启动NameSever和Broker都会报错。

这个环境变量的作用是用来加载$ROCKETMQ_HOME/conf下的除broker.conf以外的几个配置文件。所以实际情况中,可以不按这个配置,但是一定要能找到配置文件。

运行

RocketMQ组件结构
在这里插入图片描述
RocketMQ由以下这几个组件组成, 要启动RocketMQ服务,需要先启动NameServer。

  • NameServer : 提供轻量级的Broker路由服务。
  • Broker:实际处理消息存储、转发等服务的核心组件。
  • Producer:消息生产者集群。通常是业务系统中的一个功能模块。
  • Consumer:消息消费者集群。通常也是业务系统中的一个功能模块。

rocketmq集群包括nameserver和broker,nameserver负责管理集群的列表信息,broker是真正作为消息承载和提供数据吞吐服务的

启动NameServer

修改 bin/runserver.sh, 将JVM内存调小一点, 比如256m, 因为机器只有1c2g, 而且学习测试用没必要搞太大, 然后调整 mqnamesrv 的执行权限chmod 777 mqnamesrv

JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

然后用静默启动的方式启动NameServer服务, 我在 /application/rocketmq-4.7.1/mrathena 下创建了 name.server.standalone.start.sh

#!/bin/sh
# nohup Command [ Arg ... ] [ & ]
# nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示“and”的符号)到命令的尾部。
# 操作系统中有三个常用的流:0:标准输入流 stdin, 1:标准输出流 stdout, 2:标准错误流 stderr
# 一般当我们用 >console.txt,实际是 1>console.txt的省略用法;< console.txt ,实际是 0 < console.txt的省略用法。
# 带&的命令行,即使terminal(终端)关闭,或者电脑死机程序依然运行
# 2>&1, 把标准错误(2)重定向到标准输出中(1),而标准输出又导入文件output里面,所以结果是标准错误和标准输出都导入文件output里面了
# mqnamesrv 最终调用了 runserver.sh
nohup ../bin/mqnamesrv >name.server.9876.log 2>&1 &

启动完成后,在name.server.9876.log里看到这一条关键日志就是启动成功了。并且使用jps指令可以看到有一个NamesrvStartup进程。

Java HotSpot(TM) 64-Bit Server VM warning: Using the DefNew young collector with the CMS collector is deprecated and will likely be removed in a future release
Java HotSpot(TM) 64-Bit Server VM warning: UseCMSCompactAtFullCollection is deprecated and will likely be removed in a future release.
The Name Server boot success. serializeType=JSON

启动Broker

修改 bin/runbroker.sh, 将JVM内存调小一点, 比如256m, 然后调整 mqbroker 的执行权限 chmod 777 mqbroker

JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"

然后修改conf/broker.conf, 添加 autoCreateTopicEnable=true, 可以自动创建主题(生产不建议配置)

autoCreateTopicEnable=true
# 如果需要公网访问的话, 需要配置公网ip, 不然NameServer返回给Producer的是内网ip, 无法连接
brokerIP1=116.62.162.48

然后用静默启动的方式启动Broker服务, 我在 /application/rocketmq-4.7.1/mrathena 下创建了 broker.standalone.start.sh

#!/bin/sh
# -n localhost:9876, 用于指定NameServer服务地址, 不指定无法正常工作
# mqbroker 最终调用了 runbroker.sh
nohup ../bin/mqbroker -n localhost:9876 -c ../conf/broker.conf >broker.10911.log 2>&1 &

启动完成后,在broker.10911.log里有这一条关键日志就标识启动成功了。 并且jps指令可以看到一个BrokerStartup进程。

The broker[mrathena, 172.16.138.202:10911] boot success. serializeType=JSON and name server is localhost:9876

在观察runserver.sh和runbroker.sh时,可以查看到其他的JVM执行参数,这些参数都可以进行定制。而且nameServer使用的是CMS垃圾回收器,而Broker使用的是G1垃圾回收器。

命令行快速验证

在RocketMQ的安装包中,提供了一个tools.sh工具可以用来在命令行快速验证RocketMQ服务。进入RocketMQ的安装目录:

首先需要配置一个环境变量NAMESRV_ADDR指向我们启动的NameServer服务。我个人不太喜欢这种配置方法 …

export NAMESRV_ADDR='localhost:9876'

然后启动消息生产者发送消息:默认会发1000条消息

chmod 777 tools.sh
./tools.sh org.apache.rocketmq.example.quickstart.Producer

发送消息的日志, 比较尴尬, 阿里云1c2g的机器内存不足了, 把前面的两个配置再次减半

Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000d0000000, 805306368, 0) failed; error='Cannot allocate memory' (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 805306368 bytes for committing reserved memory.
# An error report file with more information is saved as:
# /application/rocketmq-4.7.1/bin/hs_err_pid18574.log

终于可以正常测试了, 然后又出问题了, 看样子像是没有找到TopicTest这个topic, 但是我已经配置了 autoCreateTopicEnable=true , 貌似不管用

22:29:51.935 [main] DEBUG i.n.u.i.l.InternalLoggerFactory - Using SLF4J as the default logging framework
RocketMQLog:WARN No appenders could be found for logger (io.netty.util.internal.PlatformDependent0).
RocketMQLog:WARN Please initialize the logger system properly.
org.apache.rocketmq.client.exception.MQClientException: No route info of this topic: TopicTest
See http://rocketmq.apache.org/docs/faq/ for further details.
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:685)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1343)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1289)
	at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:325)
	at org.apache.rocketmq.example.quickstart.Producer.main(Producer.java:67)

追查原因应该是环境变量NAMESRV_ADDR是在broker启动之后才配置的, 导致broker没有读到name.server的信息, 可以在启动broker的时候后面加上 -n localhost:9876 就可以了, 重新测试后可以看到如下日志

22:40:28.899 [main] DEBUG i.n.u.i.l.InternalLoggerFactory - Using SLF4J as the default logging framework
RocketMQLog:WARN No appenders could be found for logger (io.netty.util.internal.PlatformDependent0).
RocketMQLog:WARN Please initialize the logger system properly.
SendResult [sendStatus=SEND_OK, msgId=AC108ACA4A6A6D6F6E2823C3B9DA0000, offsetMsgId=AC108ACA00002A9F0000000000000000, messageQueue=MessageQueue [topic=TopicTest, brokerName=mrathena, queueId=3], queueOffset=0]
SendResult [sendStatus=SEND_OK, msgId=AC108ACA4A6A6D6F6E2823C3BA200001, offsetMsgId=AC108ACA00002A9F00000000000000C9, messageQueue=MessageQueue [topic=TopicTest, brokerName=mrathena, queueId=0], queueOffset=0]
SendResult [sendStatus=SEND_OK, msgId=AC108ACA4A6A6D6F6E2823C3BA270002, offsetMsgId=AC108ACA00002A9F0000000000000192, messageQueue=MessageQueue [topic=TopicTest, brokerName=mrathena, queueId=1], queueOffset=0]
SendResult [sendStatus=SEND_OK, msgId=AC108ACA4A6A6D6F6E2823C3BA320003, offsetMsgId=AC108ACA00002A9F000000000000025B, messageQueue=MessageQueue [topic=TopicTest, brokerName=mrathena, queueId=2], queueOffset=0]
SendResult [sendStatus=SEND_OK, msgId=AC108ACA4A6A6D6F6E2823C3BA390004, offsetMsgId=AC108ACA00002A9F0000000000000324, messageQueue=MessageQueue [topic=TopicTest, brokerName=mrathena, queueId=3], queueOffset=1]
# ...
SendResult [sendStatus=SEND_OK, msgId=AC108ACA4A6A6D6F6E2823C3C45B03E6, offsetMsgId=AC108ACA00002A9F00000000000316F4, messageQueue=MessageQueue [topic=TopicTest, brokerName=mrathena, queueId=1], queueOffset=249]
SendResult [sendStatus=SEND_OK, msgId=AC108ACA4A6A6D6F6E2823C3C45C03E7, offsetMsgId=AC108ACA00002A9F00000000000317BF, messageQueue=MessageQueue [topic=TopicTest, brokerName=mrathena, queueId=2], queueOffset=249]
22:40:32.394 [NettyClientSelector_1] INFO  RocketmqRemoting - closeChannel: close the connection to remote address[127.0.0.1:9876] result: true
22:40:32.404 [NettyClientSelector_1] INFO  RocketmqRemoting - closeChannel: close the connection to remote address[172.16.138.202:10911] result: true

这日志中,上面部分就是发送的消息的内容。后面两句标识消息生产者正常关闭。然后启动消息消费者接收消息:

./tools.sh  org.apache.rocketmq.example.quickstart.Consumer

启动后,可以看到消费到的消息。

22:47:05.197 [main] DEBUG i.n.u.i.l.InternalLoggerFactory - Using SLF4J as the default logging framework
Consumer Started.
ConsumeMessageThread_1 Receive New Messages: [MessageExt [brokerName=mrathena, queueId=1, storeSize=201, queueOffset=250, sysFlag=0, bornTimestamp=1607352414501, bornHost=/172.16.138.202:52202, storeTimestamp=1607352414514, storeHost=/172.16.138.202:10911, msgId=AC108ACA00002A9F000000000003188A, commitLogOffset=202890, bodyCRC=613185359, reconsumeTimes=0, preparedTransactionOffset=0, toString()=Message{topic='TopicTest', flag=0, properties={MIN_OFFSET=0, MAX_OFFSET=500, CONSUME_START_TIME=1607352426086, UNIQ_KEY=AC108ACA4AE26D6F6E2823C999240000, CLUSTER=DefaultCluster, WAIT=true, TAGS=TagA}, body=[72, 101, 108, 108, 111, 32, 82, 111, 99, 107, 101, 116, 77, 81, 32, 48], transactionId='null'}]]
# ...

日志中MessageExt后的整个内容就是一条完整的RocketMQ消息。我们要对这个消息的结构有个大概的了解,后面会对这个消息进行深入的理解。其中比较关键的属性有:brokerName,queueId,msgId,topic,cluster,tags,body,transactionId。先找下这些属性在哪里。

而这个Consume指令并不会结束,他会继续挂起,等待消费其他的消息。可以使用CTRL+C停止该进程。

搭建管理控制台

RocketMQ源代码中并没有提供控制台,但是有一个Rocket的社区扩展项目中提供了一个控制台

https://github.com/apache/rocketmq-externals

下载下来后,进入其中的rocket-console目录,这是一个maven应用, 找到resources中的application.properties配置文件, 修改 rocketmq.config.namesrvAddr=localhost:9876rocketmq.config.namesrvAddr=worker1:9876;worker2:9876;worker3:9876, 也可以修改一下 server.port=8080, 然后使用maven进行编译, mvn clean package -Dmaven.test.skip=true, 在target目录下找到 rocketmq-console-ng-1.0.1.jar, 并将其上传到服务器, 然后静默启动 nohup java -jar rocketmq-console-ng-1.0.1.jar &, 日志即为 nohup.log, 可以通过 http://ip:8080 来访问, 或者配置到 nginx 中

在管理页面的右上角可以选择语言
在这里插入图片描述

关闭RocketMQ服务

要关闭RocketMQ服务可以通过mqshutdown脚本直接关闭

chmod 777 mqshutdown
# 关闭NameServer
./mqshutdown namesrv
# 关闭Broker
./mqshutdown broker

效果如下

[root@mrathena /application/rocketmq-4.7.1/bin]# ./mqshutdown namesrv
The mqnamesrv(18696) is running...
Send shutdown request to mqnamesrv(18696) OK
[root@mrathena /application/rocketmq-4.7.1/bin]# ./mqshutdown broker
The mqbroker(18982) is running...
Send shutdown request to mqbroker(18982) OK
[root@mrathena /application/rocketmq-4.7.1/bin]# jps
11184 jar
19369 Jps
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值