Java 避免需要设置jmxremote端口(远程使用VisualVM)?
我们共享一个用于开发各种Java应用程序的远程Linux设备,并使用VisualVM over ssh来评测这些应用程序。有没有办法在Java进程上启用JMX/评测,而不需要在进程/用户之间分配/提供端口号?总是要确保只为启用评测而指定(唯一)端口号,这很烦人 更具体地说:硬编码端口显然不起作用,而且会产生冲突:Java 避免需要设置jmxremote端口(远程使用VisualVM)?,java,jvm,jmx,jvm-hotspot,visualvm,Java,Jvm,Jmx,Jvm Hotspot,Visualvm,我们共享一个用于开发各种Java应用程序的远程Linux设备,并使用VisualVM over ssh来评测这些应用程序。有没有办法在Java进程上启用JMX/评测,而不需要在进程/用户之间分配/提供端口号?总是要确保只为启用评测而指定(唯一)端口号,这很烦人 更具体地说:硬编码端口显然不起作用,而且会产生冲突: exec java -Dcom.sun.management.jmxremote.port=3000 ... 我们可以要求在运行进程时始终指定一个唯一的端口,但这很繁琐——您必须确保
exec java -Dcom.sun.management.jmxremote.port=3000 ...
我们可以要求在运行进程时始终指定一个唯一的端口,但这很繁琐——您必须确保您的端口不会与其他进程冲突,也不会与其他用户冲突:
exec java -Dcom.sun.management.jmxremote.port=$1 ...
目前我们使用:
exec java -Dcom.sun.management.jmxremote.port=$(( $RANDOM + 2000 )) ...
但我们仍然偶尔会遇到被占用的端口号
我们可以继续使用更高级的脚本(例如,查询
netstat
以查找已占用的端口号并希望没有竞争),但我们想知道是否有更好的方法/我们是否做错了。我的最佳猜测是,您应该找出是否有一种方法可以在没有竞争的情况下启动VM
-Dcom.sun.management.jmxremote.port=3000…
,然后启动自己的MBeanServer连接器
是sun jvm根据传入的系统属性启动连接器的地方,我认为阅读那里的代码将提供足够的信息来启动您自己的MBeanServerConnector
传递给newJMXConnectorServer的环境变量似乎只是一个映射,如果您从JDK读取代码,您可能会发现应该在映射中放置什么,以便它用您自己的代码启动一个连接器,然后您可以编写自己的java代码来选择可用的端口号。我没有尝试过这种方法,但它似乎很有希望,我真的很想回答你提出的问题
JMXConnectorServer connServer = null;
735 try {
736 connServer =
737 JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
738 connServer.start();
739 } catch (IOException e) {
740 if (connServer == null) {
741 throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
742 e, url.toString());
743 } else {
744 throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
745 e, connServer.getAddress().toString());
746 }
747 }
一种可能的解决方案是在remote box上运行VisualVM,并使用vnc或remote X会话在本地计算机上显示VisualVM。从Java应用程序中启动服务器不是将问题向下推一层吗?这将使端口查找更加健壮(因为我可以尝试多个端口,并且不可能出现TOCTTOU竞赛),但我也希望避免将此添加到我们正在进行的所有项目中。不管怎样,我也希望有什么能解决这个问题。