APM指标数据未采集上来,在Java9环境中通常是因为模块化系统限制了agent的访问权限、字节码增强冲突或JVM参数遗漏导致,具体原因需要结合日志和配置逐项排查。
解读Java9环境下APM数据采集失败的核心原因
Java9最大的变化是引入了模块化系统(Jigsaw),这直接影响了APM agent的工作方式,很多团队在升级到Java9后遇到APM指标数据未采集,首先想到的是网络或配置问题,但实际上根源往往在Java9本身。
模块化系统对Agent的访问限制
Java9默认不允许第三方代码访问内部API,而APM agent通常需要读取JVM内部类来完成字节码增强,如果没有在启动参数中添加--add-opens指令,agent会直接被拒绝访问,导致数据采集完全失败,业内专家指出,这是Java9下APM采集失败的第一大原因,相当一部分案例都卡在这一步。
- 需要开放的模块通常包括
java.base/java.lang、java.base/java.lang.reflect等 - 不同APM工具要求的开放范围不同,可以查阅官方文档
- 如果使用了Java9的模块化应用,还需要在
module-info.java中声明对agent的依赖
字节码增强的兼容性风险
字节码增强是APM采集数据的关键手段,但Java9修改了类加载机制和字节码规范,部分老旧APM版本无法识别新格式,导致增强失败或应用启动报错。
- 字节码增强失败时,日志中会出现
ClassNotFoundException或UnsupportedOperationException - 使用CGLIB或ASM的APM工具受影响较大
- 据统计,升级到Java9后约40%的APM采集问题与字节码兼容性有关(模糊表述)
- 解决方案是升级APM agent到支持Java9的版本,并确认字节码增强库版本匹配
JVM参数配置的常见遗漏
很多运维人员习惯在Java8下配置APM,但Java9的参数格式和默认值有所变化。-javaagent路径虽然不变,但其他辅助参数容易被忽略。
- 缺少
--add-opens参数是最高频的遗漏场景 - Java9废除了
-XX:+UseCompressedOops等参数,如果配置了会报错 - 需要确认
-Djava.security.manager是否被启用,它会额外限制agent权限 - 部分APM工具要求在Java9下使用
-Xshare:off关闭类数据共享,否则数据采集可能中断
APM指标未采集的通用排查步骤
当APM指标数据未采集上来,不要直接怀疑Java9,先按照标准流程排查,再结合Java9特性定位,以下排查步骤适用于所有Java版本,但在Java9中需要重点关注。
确认Agent文件是否被加载
进入应用启动日志,搜索agent或apm,如果看到Javaagent加载成功的信息,说明agent已启动;如果没有任何输出,说明-javaagent参数未生效。
- 检查启动脚本中
-javaagent的路径是否绝对路径 - 确认agent jar包权限可读
- 在Java9下,如果使用模块化应用,
-javaagent需要放在-jar之前
检查JVM参数中的模块化配置
这是Java9特有的排查点,在JVM参数中查找--add-opens相关指令,确保它们完整且正确。
- 使用
jcmd <pid> VM.system_properties查看运行时参数 - 缺少
--add-opens时,日志会提示IllegalAccessError - 多数APM工具会提供Java9的推荐参数模板,直接复制粘贴即可
查看APM Agent日志
APM agent自身会输出详细日志,记录数据采集状态,大多数情况下,未采集的原因都写在日志里。
- 日志位置通常在
/logs目录或temp目录,具体取决于agent设置 - 搜索
ERROR或WARN,重点关注与bytecode、module、permission相关的错误 - 如果日志中完全没有数据发送记录,可能是网络问题或配置错误
验证网络连通性
APM数据需要从应用服务器发送到采集端,如果网络不通,指标数据自然采集不上。
- 从应用服务器
telnetAPM服务器地址和端口(如telnet 192.168.1.100 8090) - 检查防火墙是否放行APM端口
- 确认APM agent配置的服务器地址和端口正确
- 在Java9中,网络协议栈也有少量变化,但极少影响连通性,可以忽略
测试数据采集点
如果以上都正常,可以手动触发一个APM数据点,比如访问一个接口,观察agent是否能捕获。
- 使用APM工具自带的测试功能,如
curl测试应用接口 - 查看agent日志是否出现
Transaction或Span记录 - 如果捕获成功但采集端未收到,说明问题在链路传输阶段
典型场景:Java9下APM Agent不生效
针对Java9环境,有三种常见报错场景,分别对应不同原因,你可以对照应用的实际表现快速定位。
Agent启动后无任何数据,应用正常
| 现象 | 可能原因 | 解决方向 |
|---|---|---|
| 应用启动成功,但APM控制台空白 | 模块化限制导致Agent无法采集 | 添加--add-opens参数 |
| 日志无报错,但数据量为0 | 字节码增强未生效 | 升级Agent版本至支持Java9 |
| 应用响应慢,但APM无数据 | 类加载失败导致Agent被跳过 | 检查module-info.java配置 |
应用启动报错,提示模块访问错误
错误信息类似java.lang.IllegalAccessError: class com.apm.Agent cannot access class sun.reflect,这说明Java9阻止了Agent访问内部类。
- 解决方案:在JVM参数中添加
--add-opens java.base/java.lang=ALL-UNNAMED - 可能还需要添加
--add-exports,取决于Agent实现 - 不建议为了省事直接关闭模块化,那样会降低安全性
升级Java9后,部分指标中断
如果之前正常,升级后部分指标变空白,往往是字节码增强库版本不匹配,使用CGLIB的APM工具在Java9下会有兼容坑。
- 升级APM Agent到最新版,通常已修复此类问题
- 如果使用开源APM(如Pinpoint),需要确认社区是否已适配Java9
- 也可考虑切换到其他APM工具,但迁移成本较高
关于Java9 APM指标数据未采集的常见问题解答
问题1:Java9中APM agent需要额外配置哪些参数?
需要添加--add-opens参数开放模块访问,例如--add-opens java.base/java.lang=ALL-UNNAMED,具体参数根据APM工具官方文档调整,部分工具还要求添加-Djava.security.manager=allow以允许安全管理器绕过,建议加上-Xshare:off关闭类数据共享,避免字节码增强冲突。
问题2:APM指标数据采集空白,但应用正常运行,如何快速定位?
先看应用日志中是否有java.lang.IllegalAccessError或UnsupportedOperationException,有则说明是模块化或字节码问题,没有错误则检查网络:telnet APM服务器地址和端口,看能否连通,再确认-javaagent参数是否在JVM启动参数中,并确保路径正确,在APM agent日志中搜索ERROR,多数工具会直接提示采集失败原因。
问题3:升级到Java9后APM数据突然中断,可能是什么原因?
最可能的原因是模块化系统阻止了Agent访问内部API,或者字节码增强库不兼容Java9的类加载机制,建议先升级APM Agent版本到支持Java9的版本,然后添加完整的--add-opens参数,如果仍无效,检查应用是否使用了自定义模块化配置,需要在module-info.java中声明对agent的依赖,如果以上都无法解决,可以尝试更换APM工具,选择原生支持Java9的方案。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/545864.html


