java 如何将 JMX 绑定到特定接口?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/331615/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to have JMX bind to a specific interface?
提问by Marc Novakowski
I am currently starting my Java VM with the com.sun.management.jmxremote.*properties so that I can connect to it via JConsole for management and monitoring. Unfortunately, it listens on all interfaces (IP addresses) on the machine.
我目前正在使用这些com.sun.management.jmxremote.*属性启动我的 Java VM,以便我可以通过 JConsole 连接到它以进行管理和监控。不幸的是,它侦听机器上的所有接口(IP 地址)。
In our environment, there are often cases where there is more than one Java VM running on a machine at the same time. While it's possible to tell JMX to listen on different TCP ports (using com.sun.management.jmxremote.port), it would be nice to instead have JMX use the standard JMX port and just bind to a specific IP address (rather than all of them).
在我们的环境中,经常会出现多个 Java VM 同时在一台机器上运行的情况。虽然可以告诉 JMX 侦听不同的 TCP 端口(使用com.sun.management.jmxremote.port),但最好让 JMX 使用标准 JMX 端口并且只绑定到特定的 IP 地址(而不是全部)。
This would make it much easier to figure out which VM we're connecting to via JConsole (since each VM effectively "owns" its own IP address). Has anyone figured out how to make JMX listen on a single IP address or hostname?
这将使找出我们通过 JConsole 连接到哪个 VM 变得更加容易(因为每个 VM 实际上“拥有”自己的 IP 地址)。有没有人想出如何让 JMX 侦听单个 IP 地址或主机名?
回答by Ga?per
If anyone else will be losing his nerves with this ... After 10 years, they finally fixed it!
如果其他人会因为这个而失去神经...... 10年后,他们终于解决了!
Since Java 8u102 -Dcom.sun.management.jmxremote.hostbinds to the selected IP
由于 Java 8u102-Dcom.sun.management.jmxremote.host绑定到所选 IP
回答by tcurdt
Fernando already provided a link to my blog post:) ..it's not trivial. You have to provide your own RMIServerSocketFactoryImpl that creates sockets on the wanted address.
Fernando 已经提供了我的博客文章的链接:) ..这不是微不足道的。您必须提供自己的 RMIServerSocketFactoryImpl 以在所需地址上创建套接字。
If internal/external interfaces are the problem and you have local access setting up a local firewall might be easier.
如果内部/外部接口是问题并且您具有本地访问权限,则设置本地防火墙可能会更容易。
回答by Niranjan
I haven't tried this but this may help.
我没有试过这个,但这可能会有所帮助。
the main nuisance here was that there is no easy way to specify the host IP address for JMX to bind to, it would always bind to all interfaces. The 'java.rmi.server.hostname' property did not work and I didn't want to pick different ports for all the different instances on the same host.
这里的主要麻烦是没有简单的方法来指定 JMX 绑定到的主机 IP 地址,它总是绑定到所有接口。'java.rmi.server.hostname' 属性不起作用,我不想为同一主机上的所有不同实例选择不同的端口。
Also, I didn't want to create my own RMIServerSocketFactory with all the complexities associated with it, I was after a simple patch to the existing code.
此外,我不想创建自己的 RMIServerSocketFactory 并具有与之相关的所有复杂性,我正在对现有代码进行简单的修补。
I've fixed this by patching the default JVM RMI socket factory that is responsible for creating this server socket. It now supports the new 'com.sun.management.jmxremote.host' property.
我通过修补负责创建此服务器套接字的默认 JVM RMI 套接字工厂来解决此问题。它现在支持新的“com.sun.management.jmxremote.host”属性。
To get this to work, save the Java code below into a file named sun/rmi/transport/proxy/RMIDirectSocketFactory.java.
要使其工作,请将下面的 Java 代码保存到名为 sun/rmi/transport/proxy/RMIDirectSocketFactory.java 的文件中。
Compile and create jmx_patch.jar from it and place it into the tomcat lib/ folder.
从中编译并创建 jmx_patch.jar 并将其放入 tomcat lib/ 文件夹中。
You then need to add the following line to bin/setenv.sh:
然后,您需要将以下行添加到 bin/setenv.sh:
CLASSPATH=$CLASSPATH:$CATALINA_HOME/lib/mx_patch.jar
类路径=$类路径:$CATALINA_HOME/lib/mx_patch.jar
add this option in tomcat instance start up
在tomcat实例启动时添加这个选项
-Dcom.sun.management.jmxremote.host=192.168.100.100"
-Dcom.sun.management.jmxremote.host=192.168.100.100"
This will then bind the JMX service only to address 192.168.100.100. The 2 other random RMI listening ports will still bind to all interfaces, but that is fine as they always pick a free port anyway.
然后,这会将 JMX 服务仅绑定到地址 192.168.100.100。其他 2 个随机 RMI 侦听端口仍将绑定到所有接口,但这很好,因为无论如何它们总是会选择一个空闲端口。
You can now run multiple tomcat instances on a single host with all the default ports intact (e.g. 8080 for JMX for all of them).
您现在可以在单个主机上运行多个 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);
}
}
}
回答by Roy Sigurd Karlsbakk
I just tried
我刚试过
-Dcom.sun.management.jmxremote.host=
-Dcom.sun.management.jmxremote.host=
with openjdk 1.8, and it works well. It binds to that addess (according to netstat) and all looks right (and works).
使用 openjdk 1.8,它运行良好。它绑定到那个地址(根据 netstat)并且一切看起来都正确(并且有效)。
回答by sosiouxme
The accepted answer is pretty old. There are some indications that Java now provides some options to enable this. For instance I have seen:
接受的答案已经很旧了。有一些迹象表明 Java 现在提供了一些选项来实现这一点。比如我见过:
-Djava.rmi.server.hostname=<YOUR_IP>
...as well as...
...也...
-Dcom.sun.management.jmxremote.host=<YOUR_IP>
However, at least on my system under jdk 1.7, these do not seem to have any effect - the JMX connector still binds to *. An updated answer (with specific applicable versions) would be much appreciated. This shouldbe simple.
但是,至少在 jdk 1.7 下的我的系统上,这些似乎没有任何影响 - JMX 连接器仍然绑定到 *. 更新的答案(具有特定的适用版本)将不胜感激。这应该很简单。

