CentOS 7 本地安装 RocketMQ 5.3.2 完整教程:含 systemd 自启动、JAVA_HOME 排障、消息收发验证
封面摘要
本文详细记录了在 CentOS 7 环境下本地安装 Apache RocketMQ 5.3.2 的完整过程,包括环境准备、目录规划、二进制安装、broker.conf 配置、systemd 开机自启配置,以及一次典型故障排查:rocketmq-broker.service 启动失败,最终定位为 systemd 环境未正确注入 JAVA_HOME 与 PATH。文末附带常见问题 FAQ,适合本地开发、测试联调和遗留环境维护参考。
导语
最近在一台 CentOS 7 服务器上本地安装 RocketMQ,用于开发环境消息队列联调。
原本以为只是常规安装,结果在接入 systemd 自启动时,rocketmq-broker.service 一直失败重启。
最终排查发现,问题并不在 RocketMQ 配置,而是在 systemd 启动环境与交互式 shell 环境不一致,导致 RocketMQ 脚本无法找到 Java。
这篇文章把整个过程完整整理出来,目标只有一个:
让你在 CentOS 7 上能够一次性把 RocketMQ 装好、跑通、托管起来,并且遇到
JAVA_HOME相关问题时能快速定位。
关键词
CentOS 7 RocketMQ RocketMQ 5.3.2 systemd JAVA_HOME JDK8 Broker 启动失败 mqbroker mqnamesrv 消息队列安装教程
一、环境信息
本文使用的实际环境如下:
- 操作系统:CentOS 7
- RocketMQ 版本:5.3.2
- JDK 版本:JDK 8
- JDK 安装目录:
/usr/java/jdk1.8.0_401 - NameServer 地址:
192.168.174.100:9876 - Broker 对外地址:
192.168.174.100
二、为什么在 CentOS 7 上选 RocketMQ
如果你当前环境还是 CentOS 7 + JDK8,那么 RocketMQ 是比较合适的本地 MQ 方案,原因主要有两点:
1. 与 JDK8 兼容性较好
RocketMQ 本地运行要求是:
- 64 位系统
- JDK 1.8+
这和很多遗留 Java 项目的基础环境是一致的。
2. 更适合老系统本地联调
CentOS 7 已经比较老,很多中间件的新版本对它的支持已经不理想。
而 RocketMQ 采用二进制包解压运行的方式,对这类环境更友好。
三、先说结论:本次故障的真正根因
在安装完成并配置 systemd 后,执行:
lua
sudo systemctl status rocketmq-broker
发现服务始终处于失败重启状态。
进一步查看日志:
css
sudo journalctl -u rocketmq-broker -b -n 200 --no-pager
可以看到关键报错:
ruby
which: no javac in (/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin)
readlink: 缺少操作数
dirname: 缺少操作数
ERROR: Please set the JAVA_HOME variable in your environment, We need java(x64)! !!
根因很明确
不是 broker.conf 错了,也不是端口冲突,而是:
systemd启动 RocketMQ 时,没有拿到正确的 Java 环境变量mqbroker启动脚本在执行 Java 检测时失败- 因此 Broker 直接退出,返回
status=1/FAILURE
最终修复方式
在 rocketmq-namesrv.service 和 rocketmq-broker.service 中显式加入:
javascript
Environment=JAVA_HOME=/usr/java/jdk1.8.0_401
Environment=PATH=/usr/java/jdk1.8.0_401/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
修复后,服务恢复正常。
四、安装前准备
1. 检查 Java 环境
先执行:
bash
java -version
javac -version
echo $JAVA_HOME
如果你已经确认 JDK 安装目录为:
bash
/usr/java/jdk1.8.0_401
那么后面的 systemd 配置就直接使用这个路径。
2. 一个常见误区:$JAVA_HOME 不是查看变量的方法
很多人会直接执行:
bash
$JAVA_HOME
这不是查看变量,而是把变量内容当成命令执行。
比如当 JAVA_HOME=/usr/java/jdk1.8.0_401 时,shell 会尝试执行这个目录,于是会报:
javascript
-bash: /usr/java/jdk1.8.0_401: 是一个目录
正确写法应该是:
bash
echo $JAVA_HOME
五、创建 RocketMQ 运行目录
建议单独创建运行用户与数据目录,避免直接用 root 跑服务。
bash
sudo useradd -r -m -s /sbin/nologin rocketmq || true
sudo mkdir -p /opt/rocketmq
sudo mkdir -p /data/rocketmq/store
sudo mkdir -p /data/rocketmq/logs
sudo chown -R rocketmq:rocketmq /opt/rocketmq /data/rocketmq
六、下载并解压 RocketMQ 5.3.2
bash
cd /opt/rocketmq
sudo wget https://dist.apache.org/repos/dist/release/rocketmq/5.3.2/rocketmq-all-5.3.2-bin-release.zip
sudo unzip rocketmq-all-5.3.2-bin-release.zip -d /opt/rocketmq/
RMQ_HOME=$(find /opt/rocketmq -mindepth 1 -maxdepth 1 -type d -name "rocketmq*" | head -n 1)
sudo ln -sfn "$RMQ_HOME" /opt/rocketmq/current
sudo chown -R rocketmq:rocketmq /opt/rocketmq
检查目录:
bash
ls -l /opt/rocketmq
ls -l /opt/rocketmq/current
七、配置 Broker
创建 broker.conf:
ini
sudo tee /opt/rocketmq/current/conf/broker.conf > /dev/null <<'EOF'
brokerClusterName=DefaultCluster
brokerName=broker-a
brokerId=0
deleteWhen=04
fileReservedTime=48
brokerRole=ASYNC_MASTER
flushDiskType=ASYNC_FLUSH
namesrvAddr=192.168.174.100:9876
listenPort=10911
brokerIP1=192.168.174.100
autoCreateTopicEnable=true
storePathRootDir=/data/rocketmq/store
storePathCommitLog=/data/rocketmq/store/commitlog
storePathConsumeQueue=/data/rocketmq/store/consumequeue
storePathIndex=/data/rocketmq/store/index
storeCheckpoint=/data/rocketmq/store/checkpoint
abortFile=/data/rocketmq/store/abort
EOF
sudo chown rocketmq:rocketmq /opt/rocketmq/current/conf/broker.conf
参数说明
namesrvAddr:Broker 连接的 NameServer 地址listenPort=10911:Broker 监听端口brokerIP1:Broker 注册给客户端的可访问地址storePath*:消息数据与索引存储目录
八、先手工启动,再上 systemd
这个顺序很重要。
很多人一上来就写 systemd,一旦失败,定位难度会大很多。
更合理的方式是:
- 先手工启动 NameServer
- 再手工启动 Broker
- 验证能发消息、能消费
- 最后再交给
systemd
九、手工启动 RocketMQ
1. 切换到运行用户
bash
sudo su -s /bin/bash rocketmq
2. 启动 NameServer
bash
cd /opt/rocketmq/current
nohup sh bin/mqnamesrv > /data/rocketmq/logs/namesrv.out 2>&1 &
查看日志:
bash
tail -f /home/rocketmq/logs/rocketmqlogs/namesrv.log
如果看到:
arduino
The Name Server boot success..
说明 NameServer 正常启动。
3. 启动 Broker + Proxy
bash
cd /opt/rocketmq/current
nohup sh bin/mqbroker -n 192.168.174.100:9876 -c conf/broker.conf --enable-proxy > /data/rocketmq/logs/broker.out 2>&1 &
查看日志:
bash
tail -f /home/rocketmq/logs/rocketmqlogs/proxy.log
如果看到类似 boot success,说明 Broker 与 Proxy 启动成功。
十、配置 systemd 开机自启
手工启动没问题后,再配置服务托管。
1. 配置 NameServer 服务
ini
sudo tee /etc/systemd/system/rocketmq-namesrv.service > /dev/null <<'EOF'
[Unit]
Description=RocketMQ NameServer
After=network.target
[Service]
Type=simple
User=rocketmq
Group=rocketmq
WorkingDirectory=/opt/rocketmq/current
Environment=JAVA_HOME=/usr/java/jdk1.8.0_401
Environment=PATH=/usr/java/jdk1.8.0_401/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
ExecStart=/bin/sh /opt/rocketmq/current/bin/mqnamesrv
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
2. 配置 Broker 服务
ini
sudo tee /etc/systemd/system/rocketmq-broker.service > /dev/null <<'EOF'
[Unit]
Description=RocketMQ Broker
After=network.target rocketmq-namesrv.service
Requires=rocketmq-namesrv.service
[Service]
Type=simple
User=rocketmq
Group=rocketmq
WorkingDirectory=/opt/rocketmq/current
Environment=JAVA_HOME=/usr/java/jdk1.8.0_401
Environment=PATH=/usr/java/jdk1.8.0_401/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
ExecStart=/bin/sh /opt/rocketmq/current/bin/mqbroker -n 192.168.174.100:9876 -c /opt/rocketmq/current/conf/broker.conf --enable-proxy
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
十一、加载并启动服务
bash
sudo systemctl daemon-reload
sudo systemctl enable rocketmq-namesrv
sudo systemctl enable rocketmq-broker
sudo systemctl restart rocketmq-namesrv
sudo systemctl restart rocketmq-broker
查看状态:
lua
sudo systemctl status rocketmq-namesrv --no-pager -l
sudo systemctl status rocketmq-broker --no-pager -l
十二、验证端口与消息收发
1. 检查端口
css
sudo lsof -i:9876
sudo lsof -i:10911
sudo lsof -i:8081
2. 验证消息发送与消费
bash
export NAMESRV_ADDR=192.168.174.100:9876
cd /opt/rocketmq/current
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
如果生产者输出:
SEND_OK
消费者输出:
sql
Receive New Messages
说明 RocketMQ 已正常工作。
十三、完整排障复盘
这次问题非常典型,值得单独总结。
故障现象
rocketmq-broker.service启动失败systemctl status中只看到不断重启- 没有第一时间暴露根因
排查动作
先看服务状态:
lua
sudo systemctl status rocketmq-broker --no-pager -l
再看系统日志:
css
sudo journalctl -u rocketmq-broker -b -n 200 --no-pager
日志关键点
vbnet
which: no javac in (...)
ERROR: Please set the JAVA_HOME variable in your environment, We need java(x64)! !!
为什么 shell 里能用 Java,systemd 却不行
因为:
- 交互式 shell 会加载
/etc/profile、~/.bash_profile等环境配置 systemd启动服务时不会自动继承这些变量- 所以命令行能跑,不代表服务也能跑
最终修复方式
在 service 文件中显式加入:
javascript
Environment=JAVA_HOME=/usr/java/jdk1.8.0_401
Environment=PATH=/usr/java/jdk1.8.0_401/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
十四、建议收藏的一套排障命令
RocketMQ 启动失败时,优先跑这几条:
lua
sudo systemctl status rocketmq-broker --no-pager -l
sudo journalctl -u rocketmq-broker -b -n 200 --no-pager
sudo journalctl -u rocketmq-namesrv -b -n 200 --no-pager
sudo -u rocketmq tail -n 100 /home/rocketmq/logs/rocketmqlogs/broker.log
sudo -u rocketmq tail -n 100 /home/rocketmq/logs/rocketmqlogs/proxy.log
sudo -u rocketmq tail -n 100 /home/rocketmq/logs/rocketmqlogs/namesrv.log
十五、可直接复制执行的最终命令清单
1. 创建目录和用户
bash
sudo useradd -r -m -s /sbin/nologin rocketmq || true
sudo mkdir -p /opt/rocketmq /data/rocketmq/store /data/rocketmq/logs
sudo chown -R rocketmq:rocketmq /opt/rocketmq /data/rocketmq
2. 下载和解压
bash
cd /opt/rocketmq
sudo wget https://dist.apache.org/repos/dist/release/rocketmq/5.3.2/rocketmq-all-5.3.2-bin-release.zip
sudo unzip rocketmq-all-5.3.2-bin-release.zip -d /opt/rocketmq/
RMQ_HOME=$(find /opt/rocketmq -mindepth 1 -maxdepth 1 -type d -name "rocketmq*" | head -n 1)
sudo ln -sfn "$RMQ_HOME" /opt/rocketmq/current
sudo chown -R rocketmq:rocketmq /opt/rocketmq
3. 启动服务
bash
sudo systemctl daemon-reload
sudo systemctl enable rocketmq-namesrv
sudo systemctl enable rocketmq-broker
sudo systemctl restart rocketmq-namesrv
sudo systemctl restart rocketmq-broker
4. 验证消息
bash
export NAMESRV_ADDR=192.168.174.100:9876
cd /opt/rocketmq/current
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
结尾 FAQ
Q1:为什么我命令行里能执行 java -version,但 systemd 启动 RocketMQ 还是报找不到 Java?
因为命令行和 systemd 的环境变量不是同一套。
你的 shell 可能加载了 JAVA_HOME,但 systemd 没有继承,所以必须在 service 文件中显式配置 Environment=JAVA_HOME=... 和 Environment=PATH=...。
Q2:brokerIP1 应该写 127.0.0.1 还是服务器 IP?
看你的访问方式:
- 只在本机联调:可以写
127.0.0.1 - 其他机器、Java 服务、客户端通过局域网访问:必须写真实服务器 IP
如果写错,客户端可能连上 NameServer,但拿到的 Broker 地址不可达。
Q3:为什么要先手工启动,再配置 systemd?
因为这样更容易定位问题:
- 手工启动失败,可以直接看到报错
systemd启动失败,往往只看到退出码,需要再翻日志
先手工跑通,再交给服务托管,排障效率最高。
Q4:执行 $JAVA_HOME 为什么会报"是一个目录"?
因为 $JAVA_HOME 会被 shell 当成命令执行。
如果变量值本身是目录路径,就会报"是一个目录"。
正确查看方式是:
bash
echo $JAVA_HOME
Q5:CentOS 7 还适合继续部署 RocketMQ 吗?
如果是:
- 本地开发
- 内网测试
- 历史环境维护
可以继续使用。
但如果是新的长期生产环境,不建议再以 CentOS 7 为基础。
更合理的方案是迁移到仍受支持的 Linux 发行版。
结语
这次安装 RocketMQ 最大的收获,不是学会了怎么解压、怎么启动,而是再次验证了一件事:
中间件安装问题,很多时候不在"软件本身",而在"运行环境一致性"。
尤其是在老系统上:
- 交互式 shell 能跑,不代表服务托管也能跑
- Java 装了,不代表
systemd找得到 - Broker 配置没错,不代表客户端就一定能访问
把这些问题一次性理顺,RocketMQ 在 CentOS 7 上跑本地开发环境其实并不复杂。