虚拟机安装RocketMQ
虚拟机安装比 Docker 更接近真实服务器环境,适合学习 RocketMQ 的进程、端口、配置文件、日志目录和 JVM 参数。它解决的是“知道服务实际怎么启动、怎么排错”的问题,而不是只会复制容器命令。
安装链路总览
flowchart TD
A["准备 JDK"] --> B["下载二进制包"]
B --> C["调整 NameServer JVM 参数"]
C --> D["调整 Broker JVM 参数"]
D --> E["启动 NameServer"]
E --> F["配置 broker.conf"]
F --> G["启动 Broker + Proxy"]
G --> H["查看日志和端口"]
H --> I["客户端发送 / 消费验证"]为什么要先启动 NameServer:Broker 启动后需要向 NameServer 注册自己的地址、Topic 和队列信息;客户端也要通过 NameServer 或 Proxy 发现路由。如果 NameServer 没起来,Broker 即使进程存在,也无法形成完整的消息链路。
下载RocketMQ资源包
RocketMQ的安装包分为两种,二进制包和源码包。由于源码包需要编译所以这里选择下载二进制包,RocketMQ下载。 
安装
RocketMQ是使用的Java语言开发的,所以需要安装Java运行时环境(要求1.8以上),安装环境这里省略。
为什么要改 JVM 参数
RocketMQ 默认参数更偏生产环境,NameServer、Broker 默认堆内存较大。学习用虚拟机通常只有 2G 或 4G 内存,如果不调整,常见后果是:
- 进程启动时直接因为内存不足失败。
- 虚拟机开始频繁 swap,命令看似执行了但服务响应很慢。
- Broker 启动后被系统 OOM Killer 杀掉。
所以本地学习可以先把堆调小,重点是跑通链路;生产环境不能简单照搬 512m,需要按消息量、堆外内存、页缓存和磁盘 IO 重新评估。
解压
unzip rocketmq-all-5.2.0-source-release.zip修改启动脚本
由于虚拟机内存比较小配置不太足而RocketMQ默认的配置(JVM内存配置为4g)又比较高一点所以需要配置下启动脚本。
进入文件目录
shellcd rocketmq-all-5.2.0-bin-release/bin编辑runserver.sh文件
shellvim runserver.sh找到如下配置:
shellchoose_gc_options() { # Example of JAVA_MAJOR_VERSION value : '1', '9', '10', '11', ... # '1' means releases before Java 9 JAVA_MAJOR_VERSION=$("$JAVA" -version 2>&1 | awk -F '"' '/version/ {print $2}' | awk -F '.' '{print $1}') if [ -z "$JAVA_MAJOR_VERSION" ] || [ "$JAVA_MAJOR_VERSION" -lt "9" ] ; then JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC" JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${GC_LOG_DIR}/rmq_srv_gc_%p_%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps" JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" else JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0" JAVA_OPT="${JAVA_OPT} -Xlog:gc*:file=${GC_LOG_DIR}/rmq_srv_gc_%p_%t.log:time,tags:filecount=5,filesize=30M" fi }修改为如下配置(可根据自己需求修改大小,注意要根据Java版本修改,我使用的是8所以只修改了else里面的配置)。
shellchoose_gc_options() { # Example of JAVA_MAJOR_VERSION value : '1', '9', '10', '11', ... # '1' means releases before Java 9 JAVA_MAJOR_VERSION=$("$JAVA" -version 2>&1 | awk -F '"' '/version/ {print $2}' | awk -F '.' '{print $1}') if [ -z "$JAVA_MAJOR_VERSION" ] || [ "$JAVA_MAJOR_VERSION" -lt "9" ] ; then JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" JAVA_OPT="${JAVA_OPT} -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:-UseParNewGC" JAVA_OPT="${JAVA_OPT} -verbose:gc -Xloggc:${GC_LOG_DIR}/rmq_srv_gc_%p_%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps" JAVA_OPT="${JAVA_OPT} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m" else JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" #JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m" #JAVA_OPT="${JAVA_OPT} -XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0" #JAVA_OPT="${JAVA_OPT} -Xlog:gc*:file=${GC_LOG_DIR}/rmq_srv_gc_%p_%t.log:time,tags:filecount=5,filesize=30M" fi }编辑runbroker.sh
shellvim runbroker.sh找到如下配置:
shellchoose_gc_options JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g" JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=15g" JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"修改为如下:
shellJAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m" JAVA_OPT="${JAVA_OPT} -XX:-OmitStackTraceInFastThrow" JAVA_OPT="${JAVA_OPT} -XX:+AlwaysPreTouch" JAVA_OPT="${JAVA_OPT} -XX:MaxDirectMemorySize=15g" JAVA_OPT="${JAVA_OPT} -XX:-UseLargePages -XX:-UseBiasedLocking"
启动
启动NameServer
启动命令
cd rocketmq-all-5.2.0-bin-release
nohup sh bin/mqnamesrv >mqnamesrv.log 2>&1 &验证启动情况
tail -f -n 500 mqnamesrv.log一下日志表示启动成功
The Name Server boot success. serializeType=JSON, address 0.0.0.0:9876启动 Broker消息存储中心和Proxy代理
修改broker配置文件
cd conf
vim broker.conf修改配置如下:
# 开启自动创建主题
autoCreateTopicEnable=true
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
# 定义服务地址,主存地址
namesrvAddr=158.50.0.2:9876
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH修改proxy配置文件
如果不修改配置文件则默认会使用8080这将会和rocketmq-dashboard端口冲突,当然也可以选择修改rocketmq-dashboard端口。
remotingListenPort:远程监听端口
grpcServerPort: grpc服务端口 //用于客户端连接(代理端口号)
{
"rocketMQClusterName": "DefaultCluster",
"remotingListenPort": 9080,
"grpcServerPort": 9081
}启动Broker
# 启动(不使用代理)
nohup sh bin/mqbroker -n localhost:9876 >mqbroker.log 2>&1 &
# 启动 Broker+Proxy
nohup sh bin/mqbroker -n localhost:9876 --enable-proxy &
# 指定配置文件启动(broker默认使用的端口是10911,我们也可以在配置文件修改端口)
nohup sh bin/mqbroker -n localhost:9876 -c conf/broker.conf --enable-proxy &验证启动情况
tail -f -n 500 nohup.out日志输出如下表示启动成功。
Thu Jul 11 09:53:08 CST 2024 rocketmq-proxy startup successfully组件启动原理
flowchart TD
A["mqnamesrv 监听 9876"] --> B["mqbroker 启动"]
B --> C["读取 broker.conf"]
C --> D["向 NameServer 注册 Broker 地址"]
D --> E["创建或加载 CommitLog / ConsumeQueue"]
E --> F["Proxy 暴露客户端接入端口"]
F --> G["Producer / Consumer 建立连接"]Broker 是消息真正落盘的地方。RocketMQ 写入消息时,会先写 CommitLog,再构建 ConsumeQueue 供消费者按队列读取。NameServer 不保存消息,它只是路由中心;所以排查“消息是否丢失”要看 Broker 日志和存储目录,而不是只看 NameServer。
常见风险和排查
| 现象 | 常见原因 | 排查方式 |
|---|---|---|
| NameServer 启动失败 | JDK 未安装、JAVA_HOME 错误、内存不足 | java -version、查看 mqnamesrv.log |
| Broker 启动失败 | JVM 参数过大、namesrvAddr 写错、端口冲突 | tail -f mqbroker.log、netstat -lntp |
| 客户端连不上 | 防火墙未放行、Broker 注册了错误 IP | 检查 brokerIP1、开放 9876/10911/Proxy 端口 |
| Dashboard 看不到 Broker | Broker 没注册到 NameServer | 查看 Broker 日志里的 register 信息 |
| 重启后消息不见 | 存储目录被清理或启动了新的空目录 | 检查 storePathRootDir 和磁盘挂载 |
最小验证 Demo
启动完成后至少做三件事:
jps
tail -n 100 mqnamesrv.log
tail -n 100 mqbroker.log如果端口正常,应该能看到 NameServer、Broker 相关 Java 进程。然后再用 Java Client 或控制台创建 Topic、发送消息、消费消息。安装不是目的,能解释“客户端如何找到 Broker、消息落在哪里、失败看哪份日志”才算真正学会。
