如何让JMX绑定到特定的接口?

我目前正在使用com.sun.management.jmxremote.*属性启动Java VM,以便我可以通过JConsole连接到它以进行管理和监视。 不幸的是,它会侦听机器上的所有接口(IP地址)。

在我们的环境中,通常情况下,同时在一台机器上运行多个Java VM。 虽然可以告诉JMX监听不同的TCP端口(使用com.sun.management.jmxremote.port ),但是让JMX使用标准JMX端口并绑定到特定的IP地址(而不是全部)会很好。他们)。

这样可以更容易地找出我们通过JConsole连接到哪个VM(因为每个VM实际上“拥有”自己的IP地址)。 有没有人想出如何让JMX监听单个IP地址或主机名?

如果有其他人会因此而失去他的神经…… 10年后,他们终于修复了它!

由于Java 8u102 -Dcom.sun.management.jmxremote.host绑定到选定的IP

请参阅: https : //bugs.openjdk.java.net/browse/JDK-6425769

费尔南多已经提供了我的博客文章的链接:) ..这不是微不足道的。 您必须提供自己的RMIServerSocketFactoryImpl,在所需地址上创建套接字。

如果内部/外部接口出现问题,并且您具有本地访问权限,则可能更容易设置本地防火墙。

我没试过,但这可能会有所帮助。

这里的主要问题是没有简单的方法来指定JMX要绑定的主机IP地址,它总是会绑定到所有接口。 ‘java.rmi.server.hostname’属性不起作用,我不想为同一主机上的所有不同实例选择不同的端口。

另外,我不想创建我自己的RMIServerSocketFactory,它具有与之相关的所有复杂性,我是在对现有代码进行简单修补之后。

我通过修补负责创建此服务器套接字的默认JVM RMI套接字工厂来修复此问题。 它现在支持新的“com.sun.management.jmxremote.host”属性。

要使其工作,请将下面的Java代码保存到名为sun / rmi / transport / proxy / RMIDirectSocketFactory.java的文件中。

从中编译并创建jmx_patch.jar并将其放入tomcat lib /文件夹中。

然后,您需要将以下行添加到bin / setenv.sh:

CLASSPATH = $ CLASSPATH:$ CATALINA_HOME / lib目录/ mx_patch.jar

在tomcat实例启动中添加此选项

-Dcom.sun.management.jmxremote.host = 192.168.100.100″

然后,这将仅将JMX服务绑定到地址192.168.100.100。 其他2个随机RMI侦听端口仍将绑定到所有接口,但这很好,因为它们总是选择一个空闲端口。

您现在可以在单个主机上运行多个tomcat实例,并且所有默认端口都保持不变(例如,对于所有这些端口,JMX为8080)。

 package sun.rmi.transport.proxy; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.rmi.server.RMISocketFactory; public class RMIDirectSocketFactory extends RMISocketFactory { public Socket createSocket(String host, int port) throws IOException { return new Socket(host, port); } public ServerSocket createServerSocket(int port) throws IOException { String jmx_host = System.getProperty("com.sun.management.jmxremote.host"); String jmx_port = System.getProperty("com.sun.management.jmxremote.port"); // Allow JMX to bind to specific address if (jmx_host != null && jmx_port != null && port != 0 && integer.toString(port).equals(jmx_port)) { InetAddress[] inetAddresses = InetAddress.getAllByName(jmx_host); if (inetAddresses.length > 0) { return new ServerSocket(port, 50, inetAddresses[0]); } } return new ServerSocket(port); } 

}

我刚试过

-Dcom.sun.management.jmxremote.host =

使用openjdk 1.8,它运行良好。 它与该addess绑定(根据netstat)并且所有看起来都正确(并且有效)。

接受的答案很古老。 有一些迹象表明Java现在提供了一些选项来实现这一点。 比如我见过:

 -Djava.rmi.server.hostname= 

…以及…

 -Dcom.sun.management.jmxremote.host= 

但是,至少在我的系统jdk 1.7下,这些似乎没有任何影响 – JMX连接器仍然绑定到*。 非常感谢更新的答案(具有特定的适用版本)。 这应该很简单。