news 2026/9/2 13:33:45

Java-216 RocketMQ 4.5.1 在 JDK9+ 从0到1全流程启动踩坑全解:脚本兼容修复(GC 参数/CLASSPATH/ext.dirs)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java-216 RocketMQ 4.5.1 在 JDK9+ 从0到1全流程启动踩坑全解:脚本兼容修复(GC 参数/CLASSPATH/ext.dirs)

TL;DR

  • 场景:RocketMQ 4.5.1 在 JDK9+ 启动被「废弃/移除的 JVM 参数」和「类路径未加载 lib」卡住。
  • 结论:删 CMS/ParNew 与 java.ext.dirs,GC 日志切 -Xlog,CLASSPATH 补 ${BASE_DIR}/lib/*。
  • 产出:runserver/runbroker/tools 三处最小改动清单 + 版本矩阵 + 错误速查卡。

版本矩阵

项目说明
RocketMQ 4.5.1文中下载与脚本修改均以4.5.1的bin包路径结构为前提(conf、lib、bin)。
JDK 8不属于本文“必须改脚本”的目标区间;旧参数体系更容易“还能跑”,但与本文JDK9+统一日志改法不同。
JDK 9–17本文修改点(删CMS/ParNew、删java.ext.dirs、-Xlog、补lib/*)面向该区间的典型兼容面。
JDK 18+文中未给出该区间的明确验证信号;仍按JDK9+逻辑处理,但不对“零差异可用”做一致性承诺。
Linux(通用)路径与命令按常见发行版shell环境编写;/etc/profile、/dev/shm、~/logs写法依赖标准目录约定。

RocketMQ 环境搭建

软件下载


我们先进入到目录,然后对软件进行下载:

cd/opt/software

接着我们通过 wget 进行下载:

wgethttps://archive.apache.org/dist/rocketmq/4.5.1/rocketmq-all-4.5.1-bin-release.zip

对应内容如下所示:

解压移动

unziprocketmq-all-4.5.1-bin-release.zipmvrocketmq-all-4.5.1-bin-release../server/rocketmq

对应的结果如下所示:

修改脚本

  • bin/runserver.sh
  • bin/runbroker.sh
  • bin/tools.sh

我们首先进入配置目录

cd/opt/server/rocketmq

runserver

vimbin/runserver.sh

根据下面的要求删除对应的内容(后续会解释为什么要删除):
删除

  • UseCMSCompactAtFullCollection
  • UseParNewGC
  • UseConcMarkSweepGC

修改内存

JAVA_OPT="${JAVA_OPT}-server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=64mm -XX:MaxMetaspaceSize=160mm"

修改gc配置

-Xloggc 修改为 -Xlog:gc

整体修改完:

#===========================================================================================# JVM Configuration#===========================================================================================JAVA_OPT="${JAVA_OPT}-server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=160m"JAVA_OPT="${JAVA_OPT}-XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8"JAVA_OPT="${JAVA_OPT}-verbose:gc -Xlog:gc:/dev/shm/rmq_srv_gc.log -XX:+PrintGCDetails"JAVA_OPT="${JAVA_OPT}-XX:-OmitStackTraceInFastThrow"JAVA_OPT="${JAVA_OPT}-XX:-UseLargePages"#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"JAVA_OPT="${JAVA_OPT}${JAVA_OPT_EXT}"JAVA_OPT="${JAVA_OPT}-cp${CLASSPATH}"

classpath 这里需要补一个:

# 原来是exportCLASSPATH=".:${BASE_DIR}/conf:CLASSPATH # 补充完 export CLASSPATH=".:${BASE_DIR}/conf:${BASE_DIR}/lib/*"

基本内容如下所示了:

broker

vimbin/runbroker.sh

修改一下JVM的参数:

-Xms256m -Xmx256m -Xmn128m

删除

  • PrintGCDateStamps
  • PrintGCApplicationStoppedTime
  • PrintAdaptiveSizePolicy
  • UseGCLogFileRotation
  • NumberOfGCLogFiles=5
  • GCLogFileSize=30m

删除:

JAVA_OPT="${JAVA_OPT}-Djava.ext.dirs=${JAVA_HOME}/jre/lib/ext:${BASE_DIR}/lib"

整体上就是删除了一大段:

#===========================================================================================# JVM Configuration#===========================================================================================JAVA_OPT="${JAVA_OPT}-server -Xms8g -Xmx8g -Xmn4g"JAVA_OPT="${JAVA_OPT}-XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30 -XX:SoftRefLRUPolicyMSPerMB=0"JAVA_OPT="${JAVA_OPT}-verbose:gc -Xloggc:/dev/shm/mq_gc_%p.log -XX:+PrintGCDetails"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"#JAVA_OPT="${JAVA_OPT} -Xdebug -Xrunjdwp:transport=dt_socket,address=9555,server=y,suspend=n"JAVA_OPT="${JAVA_OPT}${JAVA_OPT_EXT}"JAVA_OPT="${JAVA_OPT}-cp${CLASSPATH}"

classpath 这里需要补一个:

# 原来是exportCLASSPATH=".:${BASE_DIR}/conf:CLASSPATH # 补充完 export CLASSPATH=".:${BASE_DIR}/conf:${BASE_DIR}/lib/*"

整体如下:

tools

vimbin/tools.sh

删除:

JAVA_OPT="${JAVA_OPT}-Djava.ext.dirs=${BASE_DIR}/lib:${JAVA_HOME}/jre/lib/ext"

classpath 这里需要补一个:

# 原来是exportCLASSPATH=".:${BASE_DIR}/conf:CLASSPATH # 补充完 export CLASSPATH=".:${BASE_DIR}/conf:${BASE_DIR}/lib/*"

整体结果如下:

针对修改的解释

这些改动的核心动机只有一个:让 RocketMQ 的启动脚本在 JDK9+(尤其 JDK14/15+)不再因为“过时/被移除的 JVM 参数”而告警或直接启动失败,同时把 GC 日志切到 JDK9 引入的统一日志体系。

runserver:删除 CMS/ParNew 相关参数 + 换 GC 日志体系 + 改内存

删除 UseCMSCompactAtFullCollection / UseParNewGC / UseConcMarkSweepGC

  • UseConcMarkSweepGC(CMS)在 JDK9 就被标记为 deprecated,后续版本彻底移除;继续带着该参数会从“警告”变成“直接报错退出”。
  • UseParNewGC 是 CMS 时代常见的年轻代收集器搭配项;当 CMS 被移除后,这类 仅对 CMS 有意义的参数会被废弃/作废。
  • UseCMSCompactAtFullCollection 是 CMS 体系内的 Full GC 压缩控制项;同样属于 CMS 专属参数,CMS 消失后它也没有语义价值。
  • JDK9 起默认 GC 已经切换到 G1(“让 G1 成为默认”是 JDK9 的方向之一),所以很多人直接把 CMS/ParNew 参数整段删掉,避免版本兼容问题。

-Xloggc 改为 -Xlog:gc:JDK9 引入 Unified JVM Logging(统一日志框架),GC 日志也随之迁移到 -Xlog 体系;老式的 -Xloggc 与一堆 -XX:+PrintGC… 组合逐步被替代。

修改内存:-Xms/-Xmx/-Xmn/MetaspaceSize/MaxMetaspaceSize

  • -Xms/-Xmx:分别是堆初始/最大;设为相同通常是为了避免运行时扩容带来的抖动(脚本层面追求“固定堆”)。
  • -Xmn:年轻代大小(影响 minor GC 频率与停顿形态)。
  • MetaspaceSize/MaxMetaspaceSize:类元数据区阈值与上限;控制类加载相关的内存占用与触发元空间回收的节奏。

broker:删掉一批 GC 日志旧参数(因为统一日志体系不吃这套了)

  • PrintGCDateStamps
  • PrintGCApplicationStoppedTime
  • PrintAdaptiveSizePolicy
  • UseGCLogFileRotation
  • NumberOfGCLogFiles
  • GCLogFileSize

本质都属于 JDK8 及以前的“老 GC 日志开关 + 老日志轮转方式”。
JDK9+ 统一切到 -Xlog 后,这些要么被忽略、要么报 deprecated/obsolete,最终目的是把配置收敛到类似下面的能力集合:

  • 时间戳/停顿/更细粒度标签(由 -Xlog:…:time,uptime,tags,level 之类表达)
  • 文件输出与轮转(在 -Xlog 的 file 语法里完成,而不是 UseGCLogFileRotation/GCLogFileSize/… 这一套老参数)

tools:删除 -Djava.ext.dirs=…(JDK9 起扩展机制被移除)

-Djava.ext.dirs 依赖的是 JRE 的 extension classloader 机制(把 jar 放到 lib/ext 或用 java.ext.dirs 注入)。这个机制在 JDK9 因模块化运行时(JPMS)被移除;只要设置该属性,启动器就可能直接失败。
因此把 tools.sh 里这行删掉,是为了避免在 JDK9+ 上“脚本先天不兼容”的硬错误。

环境变量

配置RocketMQ的环境变量,方便我们后续进行服务启动:

vim/etc/profile
# RocketMQ 环境变量exportROCKET_HOME="/opt/server/rocketmq"exportPATH="${ROCKET_HOME}/bin:$PATH"

写入的内容如下所示:

最后记得刷新

source/etc/profile

启动服务

NameServer

mqnamesrv


查看当前的服务日志:

tail-f ~/logs/rocketmqlogs/namesrv.log

Broker

启动服务:

mqbroker -n0.0.0.0:9876

启动结果如下所示:

查看日志:

tail-f ~/logs/rocketmqlogs/broker.log

服务测试

发送消息

设置环境变量

exportNAMESRV_ADDR=0.0.0.0:9876

使用官方提供的Demo:

shbin/tools.sh org.apache.rocketmq.example.quickstart.Producer

执行结果如下所示:

接收消息

设置环境变量

exportNAMESRV_ADDR=0.0.0.0:9876

使用官方提供的Demo:

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

执行结果如下所示:

关闭RocketMQ

mqshutdown namesrv mqshutdown broker

错误速查

症状根因定位修复
Unrecognized VM option ‘UseConcMarkSweepGC’ 或直接退出JDK9+ 移除/废弃 CMS/ParNew 体系参数java -version;启动日志首屏 JVM options
从 runserver.sh 删除 UseConcMarkSweepGC/UseParNewGC/UseCMSCompactAtFullCollection(保持 G1 或默认)
GC 日志参数告警/不生效(-Xloggc、PrintGCDateStamps 等)JDK9+ 统一日志体系迁移到 -Xlog,旧开关逐步废弃搜索脚本中的 -Xloggc、PrintGC*、UseGCLogFileRotation
将 -Xloggc 改为 -Xlog:gc:…;在 broker 脚本删除老式 GC 日志与轮转参数
Error: Could not find or load main class org.apache.rocketmq.namesrv.NamesrvStartupCLASSPATH 未包含 ${BASE_DIR}/lib/*(或脚本中 CLASSPATH 拼错为字面量 CLASSPATH)导致核心类不在类路径echo $CLASSPATHbash -x mqnamesrv看最终 -cp
export CLASSPATH=".:${BASE_DIR}/conf:${BASE_DIR}/lib/*"固化到脚本;避免 …:CLASSPATH 这种字面量拼接
tools.sh 执行 Demo 报 ClassNotFound / 直接启动失败-Djava.ext.dirs=… 依赖 JRE ext 机制,JDK9 起移除在 tools.sh 搜 java.ext.dirs;观察 JVM 启动报错
删除JAVA_OPT="${JAVA_OPT} -Djava.ext.dirs=...";用CLASSPATH=conf + lib/*承载依赖
JVM 启动时报 Invalid -XX:MetaspaceSize=… 或参数解析失败参数单位/拼写错误(如 64mm)启动日志中的 “Improperly specified VM option”
-XX:MetaspaceSize=64mm修正为-XX:MetaspaceSize=64m(同理检查 MaxMetaspaceSize)
环境变量设置后仍找不到命令脚本引用目录不一致变量名不一致(如 ROCKETMQ_HOME vs ROCKET_HOME)导致脚本/命令路径判断偏离envgrep ROCKET;检查 bin 脚本对 HOME 变量的读取

其他系列

🚀 AI篇持续更新中(长期更新)

AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!
AI研究-132 Java 生态前沿 2025:Spring、Quarkus、GraalVM、CRaC 与云原生落地
🔗 AI模块直达链接

💻 Java篇持续更新中(长期更新)

Java-207 RabbitMQ Direct 交换器路由:RoutingKey 精确匹配、队列多绑定与日志分流实战
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务已完结,Dubbo已完结,MySQL已完结,MongoDB已完结,Neo4j已完结,FastDFS 已完结,OSS已完结,GuavaCache已完结,EVCache已完结,RabbitMQ正在更新… 深入浅出助你打牢基础!
🔗 Java模块直达链接

📊 大数据板块已完成多项干货更新(300篇):

包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解
🔗 大数据模块直达链接

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 16:39:46

Windows OLE零点击RCE漏洞CVE-2025-21298深度分析

理解CVE-2025–21298 CVE-2025–21298是Windows OLE中的一个零点击漏洞。OLE是一种支持文档嵌入和对象链接的技术。攻击者可以通过发送一封包含恶意RTF文档的恶意电子邮件来利用此漏洞。当受害者在Microsoft Outlook中打开或预览该邮件时,漏洞会被触发,从…

作者头像 李华
网站建设 2026/9/2 15:03:25

Flask页面跳转实战指南:五种方式与不同应用场景下的最佳选择

你在Flask开发中是否经常为页面跳转逻辑混乱而头疼?据统计,70%的Web应用性能问题源于不当的跳转处理,导致页面加载慢、用户体验差甚至安全漏洞!本文带你深入理解Flask中的五种核心跳转方式,从基础到进阶,帮…

作者头像 李华
网站建设 2026/9/2 12:36:39

Python的高校安全治安管理系统-vue

目录已开发项目效果实现截图开发技术路线相关技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!已开发项目效果实现截图 同行可拿货,招校园代理 Python的高校安全治安管理系统-vue 开发技术路线 开发语…

作者头像 李华
网站建设 2026/9/2 7:04:47

Exchange 2007 属性及GUID参考大全

Exchange 2007 属性及GUID参考大全 快速界面推理,文本转语音大模型。 镜像/应用大全,欢迎访问 官方介绍 主要改进: 🔊 更高品质:44.1kHz采样率保留了更多高频细节,以实现更好的声音克隆 ⚡ 更高效&#…

作者头像 李华
网站建设 2026/9/2 19:02:53

贝壳一面:年轻代回收频率太高,如何定位?

JVM 年轻代(Young Generation)回收频率过高 可能导致 应用性能下降、GC 开销过大,进而影响系统吞吐量。要找出 导致高频 GC 的具体原因,一般需要按照以下步骤进行分析和优化。现象分析年轻代 GC 过于频繁的常见表现:应…

作者头像 李华
网站建设 2026/9/1 8:52:13

国产自研大模型引擎崛起,Open-AutoGLM官网透露的3个战略信号

第一章:国产自研大模型引擎崛起的战略背景近年来,随着人工智能技术在全球范围内的迅猛发展,大模型已成为推动科技变革的核心驱动力。在此背景下,中国加速推进国产自研大模型引擎的研发与落地,既是应对国际技术竞争的必…

作者头像 李华