RocketMQ 5.1.4 和 JDK 21
作用:做消息的分发、削峰填谷、异步
安装 JDK 21
因为 RocketMQ 是依赖于 Java 环境的,所以虚拟机也需要有 Java 环境,现在安装个 JDK 21。
下载解压
wget https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz
tar -zxvf jdk-21_linux-x64_bin.tar.gz
[图片]
unzip 和 tar -zxvf 的区别
unzip 用来解压 zip 文件,tar -zxvf 用来解压 tar.gz 文件。
[图片]
配置环境变量
.bash_profile 是 Bash 登录 shell 的初始化配置文件,用于设置用户级环境变量、PATH、别名、函数,在用户登录 Linux 系统时自动执行。
Bash:Bourne Again Shell,是 Linux/Unix 系统的默认命令行解释器(Shell)
sudo find / -name ".bash_profile" 2>/dev/null
[图片]
我当前的 /home/ljh 这个目录是没有这个 .bash_profile 配置文件的,可以自己创建一个,用于我当前登录用户 ljh 可以使用。.bash_profile 是 Bash 登录 Shell 的初始化配置文件,用于设置用户级环境变量和启动配置。
在 .bash_profile 配置文件里面添加环境变量:
export JAVA_HOME=/home/ljh/nfturbo/middleware/java/jdk-21.0.10
export PATH=$JAVA_HOME/bin:$PATH
执行这个配置文件:
source .bash_profile
如图可以看到 JDK 的环境变量生效了,可以在任意位置查看版本号了。
[图片]
[图片]
虚拟机 安装 RocketMQ 5.1.4
重启命令
虚拟机重启之后,目前 Broker 和 NameServer 还不会自动启动,手动命令启动。
cd /home/ljh/nfturbo/middleware/rocketmq/rocketmq-all-5.1.4-bin-release
nohup sh bin/mqnamesrv -n "192.168.209.129:9876" &
nohup ./bin/mqbroker -n localhost:9876 -c conf/broker.conf autoCreateTopicEnable=true &
[图片]
然后查看是否启动成功:
ps -ef | grep broker
ps -ef | grep mqnamesrv
对比下就可以看到启动成功了。
[图片]
命令获取
官网下载地址
wget https://dist.apache.org/repos/dist/release/rocketmq/5.1.4/rocketmq-all-5.1.4-bin-release.zip
启动
启动 Name Server
cd /home/ljh/nfturbo/middleware/rocketmq/rocketmq-all-5.1.4-bin-release
nohup sh bin/mqnamesrv -n "192.168.209.129:9876" &
[图片]
[图片]
移除掉偏向锁的参数
到 /home/ljh/nfturbo/middleware/rocketmq/rocketmq-all-5.1.4-bin-release/bin 位置下的 runbroker.sh 配置文件里面,移除掉 UseBiasedLocking 这个偏向锁的参数。因为偏向锁被废弃了,所以需要移除这个 VM 参数。
vim runbroker.sh
[图片]
启动 Broker
修改 conf/broker.conf,加入:
brokerIP1=你的 ip 地址
brokerIP1=192.168.209.129
直接在 RocketMQ 根目录启动即可:
./bin/mqbroker -n localhost:9876 -c conf/broker.conf autoCreateTopicEnable=true
或者后台启动,然后回车即可:
nohup ./bin/mqbroker -n localhost:9876 -c conf/broker.conf autoCreateTopicEnable=true &
[图片]
[图片]
查看是否启动成功
ps aux | grep broker
ps aux | grep mqnamesrv
ps -ef | grep broker
ps -ef | grep mqnamesrv
ps 是 Linux/Unix 下用来查看当前系统运行进程的命令。
ps aux:显示系统中所有进程(BSD 风格)
- a:显示所有用户的进程
- u:显示用户信息
- x:显示没有控制终端的进程(比如后台进程)
grep:用来在文本中搜索匹配的字符串
[图片]
mqnamesrv 和 broker 都有进程,表示都启动成功了。
[图片]
调整内存大小
如果内存不够,修改 bin/runserver.sh 和 runbroker.sh,把内存调小一点。我这里自己测试用的,也不用太多占内存。
[图片]
[图片]
消息和日志存放位置
配置文件没改的话,日志和消息数据库位置。
[图片]
[图片]
查看日志是否启动成功
1、直接查关键字
grep "boot success" broker.log
grep "boot success" namesrv.log
[图片]
2、查看 NameServer 日志 namesrv.log
cd /home/ljh/logs/rocketmqlogs
tail -f namesrv.log
tail -n 100 /home/ljh/logs/rocketmqlogs/namesrv.log
日志显示成功启动。
[图片]
[图片]
3、查看 Broker 日志 broker.log
cd /home/ljh/logs/rocketmqlogs
tail -f broker.log
tail -n 100 /home/ljh/logs/rocketmqlogs/broker.log
日志显示成功启动。
[图片]
4:jps -l 查看当前机器上运行的 Java 程序进程
列出所有 Java 进程,并显示启动的主类或 jar 包路径。
jps -l
可以看到 Broker 和 NameServer 都启动成功了。
[图片]
Docker 安装 Dashboard
为什么 RocketMQ 安装在宿主机,而 Dashboard 安装在 Docker?
因为 RocketMQ 是核心服务(高性能组件),而 Dashboard 只是一个管理工具,放容器里更方便、更安全、更解耦。
Dashboard 是运行在 Docker 容器里的 JVM,不在宿主机 JVM 进程列表中。
命令
Docker 会从 Docker Hub 下载镜像层(layers)。下载完成后,这个镜像不是放在当前目录,而是存储在 Docker 的默认存储目录,由 Docker 管理。镜像默认存储在:/var/lib/docker。
docker pull apacherocketmq/rocketmq-dashboard:latest
docker run -d \
--name rocketmq-dashboard \
--restart unless-stopped \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.209.129:9876" \
-p 8080:8080 \
-t apacherocketmq/rocketmq-dashboard:latest
解释:
-d:关掉终端,容器还会继续运行
--restart unless-stopped:容器自动重启策略,除非手动停止,否则会自动重启
-Drocketmq.namesrv.addr=192.168.209.129:9876:Dashboard 去连接 RocketMQ NameServer
总结:从镜像创建一个容器,并在后台运行 RocketMQ Dashboard。Dashboard 是运行在 Docker 容器里的 Java 程序。
后面报错,重新安装了:
- 先拉取镜像
docker pull styletang/rocketmq-console-ng:latest
- 重新创建容器
docker run -d \
--name rocketmq-dashboard \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.209.129:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \
-p 8080:8080 \
-t styletang/rocketmq-console-ng
[图片]
启动失败
浏览器无法访问,开始排除问题。
1、查看进程
1-1:ps -ef | grep dashboard
[图片]
[图片]
1-2:docker ps
[图片]
1-3:直接看容器进程 docker top rocketmq-dashboard
[图片]
2、查看日志
2-1:容器日志路径
cd /var/lib/docker/containers
[图片]
问题:
为什么 docker logs -f rocketmq-dashboard 这个命令看日志有报错,看 ad4e0f8bbf72f76f85bee782de60260d12f10bf3d33ca6b7de62aac1097f9fd8-json.log 这个日志没有报错,不都是 dashboard 的日志吗?
回答:
两个日志是同一来源,但看到的内容不一定完全一致,因为:
docker logs 是 Docker 解析后的流式输出
*-json.log 是 Docker 原始底层日志文件
就是这个日志也有报错,只不过是 json 格式,我没看出来而已。
[图片]
2-1:通过 docker 容器名字查看日志 docker logs -f rocketmq-dashboard
docker logs -f rocketmq-dashboard
执行这个查询日志,Docker 会:
- 找到容器
rocketmq-dashboard
- 找到这个容器的日志驱动(默认 json-file)
- 读取:
/var/lib/docker/containers/<容器 ID>/<容器 ID>-json.log
- 解析 JSON
- 输出人类可读内容
只查看 100 行:
docker logs --tail 100 rocketmq-dashboard
[图片]
可以看到报错信息了。
# RocketMQ 内部调用链是:Dashboard → NameServer → Broker
# Dashboard → NameServer (查询 Broker 地址)
# Dashboard → Broker (直接通信)
# 1️⃣ Dashboard 先找 NameServer
# 2️⃣ NameServer 返回 Broker 地址
# 3️⃣ Dashboard 再自己去找 Broker,而不是 nameserver 去找 broker
这行异常是在获取 Broker 集群信息时发生的:说明 NameServer 已经返回了 Broker 信息,但 Dashboard 去连接 Broker 时失败。
RemotingConnectException: connect to null failed 和 validateObject failed, clusterInfo = null(Broker 集群信息获取失败,说明 Broker 根本没有连上)。
可以看出在控制台上无法访问 Broker。这里可以看出 NameServer 已经链接上了 ClientConfig{namesrvAddr='192.168.209.129:9876'。
[图片]
可能是启动控制台的时候 IP 地址不对。如果按照官方文档,你用的是:
docker run -d \
--name rocketmq-dashboard \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=127.0.0.1:9876" \
-p 8080:8080 \
-t apacherocketmq/rocketmq-dashboard:latest
这个命令只适用于一种情况:NameServer 和 Dashboard 在同一个容器,或者 Dashboard 直接跑在宿主机(不是 Docker)。
但是现在我是:
- NameServer:宿主机虚拟机
- Dashboard:Docker 容器
问题:可是我不是已经能连接到 NameServer 了吗,然后 NameServer 再去连接 Broker 为什么会失败?
回答:NameServer 只负责'告诉你 Broker 在哪',不做代理、不转发。
RocketMQ 内部调用链是:Dashboard → NameServer → Broker。
- Dashboard 先找 NameServer
- NameServer 返回 Broker 地址
- Dashboard 再自己去找 Broker,而不是 NameServer 去找 Broker。
那么就会有问题。因为,Docker 容器是一个容器,Docker 容器与宿主机可以看成是两个独立的服务器,在 Docker 容器内访问 127.0.0.1 或 localhost 都是访问的这个 Docker 容器本身,如果要访问宿主机的必须使用宿主机 IP。
docker run -d \
--name rocketmq-dashboard \
--link rmqserver:namesrv \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.209.129:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \
-p 8080:8080 \
-t styletang/rocketmq-console-ng
解释:
-Dcom.rocketmq.sendMessageWithVIPChannel=false:关闭 VIP 通道【一个 10909 的端口】
--link rmqserver:namesrv:这个后面被我删掉了。容器 rmqserver 可以用 hostname namesrv 访问,不过这里没用到,因为写了宿主机 IP。
styletang/rocketmq-console-ng:这个是更新的版本。
重新安装成功
停掉并删除旧容器:
docker rm -f rocketmq-dashboard
先拉取镜像:
docker pull styletang/rocketmq-console-ng:latest
重新创建容器:
docker run -d \
--name rocketmq-dashboard \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.209.129:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \
-p 8080:8080 \
-t styletang/rocketmq-console-ng
[图片]
拉取成功。
[图片]
创建容器成功。
[图片]
查看日志:
docker logs -f rocketmq-dashboard
好像没毛病。
[图片]
启动已有容器
docker start rocketmq-dashboard
设置自动重启
docker update --restart unless-stopped rocketmq-dashboard
访问成功
http://192.168.209.129:8080/#/
[图片]
代码简单集成
部署完成之后要集成到项目中。
pom
[图片]
配置文件依赖关系
spring.config.import 是干啥的?
回答:
在 Spring Boot 2.4+,官方推荐配置文件模块化,可以把不同的配置拆成多个文件,然后在主配置里导入;
作用:
- 告诉 Spring Boot 把这些文件的配置都加载到环境里;
- 顺序决定覆盖规则(后面文件可以覆盖前面文件的属性);
- 可以把配置拆模块化,便于管理;
- 所以这里的 stream.yml 被导入到整个 Spring Environment 里了。
[图片]
[图片]
Spring Boot 3 自动配置注册文件 理解
在 Spring Boot 2.x 时代,这个功能由 spring.factories 文件提供。
在 Spring Boot 3.x,官方改为 AutoConfiguration.imports 文件,它被 AutoConfigurationImportSelector 和 ImportCandidates 类加载。
[图片]
Spring Boot 会主动加载这个配置类,不依赖包扫描范围。