RMI JMXConnectorServer启动时等待两分钟问题排查求助
RMI-JMX启动绑定阶段2分10秒停顿问题排查
我们的应用部署在前端为Tomcat的服务器上,通过RMI通信,该架构稳定运行多年,但新部署Debian 12服务器时,配置JMX监控的MBeanServer阶段出现2分10秒的启动等待。
简化测试代码
import java.lang.management.ManagementFactory; import java.rmi.registry.LocateRegistry; import java.util.HashMap; import java.util.Map; import javax.management.MBeanServer; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; public class RMITest { public static void main(String[] args) throws Exception { int rmiPort = 1199; int jmxPort = 5199; String hostName = "localhost"; LocateRegistry.createRegistry(rmiPort); MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://"+hostName+":"+jmxPort+"/jndi/rmi://"+hostName+":" + rmiPort + "/jmxrmi"); System.err.println("[RMITest] main - " + url.toString()); Map<String, Object> envConf = new HashMap<>(); envConf.put("com.sun.management.jmxremote.ssl", "false"); envConf.put("com.sun.management.jmxremote.authenticate", "false"); System.err.println("[RMITest] main - Before newJMXConnectorServer" ); JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(url, envConf, mbs); System.err.println("[RMITest] main - Before start" ); cs.start(); System.err.println("[RMITest] main - after start" ); while(true) { Thread.sleep(1000); } } }
启动脚本
#!/bin/sh /usr/lib/jvm/graalvm21/bin/java -Djava.util.logging.config.file="logging.properties" -Djava.rmi.server.hostname=SERVER_IP RMITest
注:
java.rmi.server.hostname是客户端正常通信的必要配置,但添加后启动出现2分钟停顿;移除该参数则启动正常。
日志配置(logging.properties)
java.util.logging.ConsoleHandler.level = ALL javax.management.remote.rmi.level = ALL
日志输出
[RMITest] main - service:jmx:rmi://localhost:5199/jndi/rmi://localhost:1199/jmxrmi [RMITest] main - Before newJMXConnectorServer [RMITest] main - Before start Nov 06, 2024 2:43:16 PM javax.management.remote.rmi.RMIConnectorServer start FINER: setting default class loader Nov 06, 2024 2:43:16 PM javax.management.remote.rmi.RMIConnectorServer start FINER: setting RMIServer object Nov 06, 2024 2:43:16 PM javax.management.remote.rmi.RMIConnectorServer start FINER: getting RMIServer object to export Nov 06, 2024 2:43:16 PM javax.management.remote.rmi.RMIConnectorServer start FINER: Using external directory: rmi://localhost:1199/jmxrmi Nov 06, 2024 2:43:16 PM javax.management.remote.rmi.RMIConnectorServer start FINER: jmx.remote.jndi.rebind=false Nov 06, 2024 2:43:16 PM javax.management.remote.rmi.RMIConnectorServer start FINER: binding to rmi://localhost:1199/jmxrmi Nov 06, 2024 2:45:27 PM javax.management.remote.rmi.RMIConnectorServer start FINER: Connector Server Address = service:jmx:rmi://localhost:5199/jndi/rmi://localhost:1199/jmxrmi Nov 06, 2024 2:45:27 PM javax.management.remote.rmi.RMIConnectorServer start FINER: started. [RMITest] main - after start
日志显示:绑定操作(2:43:16)到连接器就绪(2:45:27)间隔恰好2分10秒,已排查DNS和防火墙配置,未发现Debian 11与12的差异,寻求排查方向。
排查方向与解决方案
1. 验证SERVER_IP的反向解析是否正常
设置java.rmi.server.hostname=SERVER_IP时,RMI/JMX会尝试对该IP进行反向DNS解析获取主机名,若解析失败或超时会触发默认2分钟DNS重试超时:
- 执行命令测试反向解析:
nslookup SERVER_IP或dig -x SERVER_IP - 若反向解析无结果,需在DNS服务器添加该IP的PTR反向记录,或在服务器本地
/etc/hosts中添加SERVER_IP 对应主机名的映射。
2. 调整Java DNS超时参数
无法修改DNS配置时,可通过系统参数缩短DNS超时:
# 添加到启动参数中 -Dsun.net.inetaddr.ttl=30 -Dsun.net.inetaddr.negative.ttl=10
sun.net.inetaddr.ttl:DNS缓存有效期(秒)sun.net.inetaddr.negative.ttl:DNS失败缓存有效期(秒)
3. 统一主机名配置
测试代码中JMXServiceURL使用localhost,但java.rmi.server.hostname设置为SERVER_IP,可能导致解析冲突,修改JMXServiceURL的hostName为实际服务器IP:
String hostName = "SERVER_IP"; // 替换为实际服务器IP
4. 排查GraalVM特殊行为
使用GraalVM 21可能存在与OpenJDK不同的RMI实现:
- 切换到OpenJDK 11/17测试,确认是否为GraalVM特定问题
- 添加参数明确指定RMI端口:
-Dcom.sun.management.jmxremote.rmi.port=1199
5. 检查系统DNS配置
Debian 12的resolv.conf配置可能与Debian 11不同:
- 查看
/etc/resolv.conf中的nameserver,确保DNS服务器可达且响应正常 - 测试反向解析得到的主机名连通性:
ping -c 2 $(nslookup SERVER_IP | grep 'name =' | awk '{print $4}')
内容的提问来源于stack exchange,提问作者user28165113
相关产品推荐
相关产品推荐

