2008-12-01 85 views
17

我目前正在启动我的Java VM,并使用属性,以便我可以通过JConsole连接到它以进行管理和监视。不幸的是,它监听机器上的所有接口(IP地址)。如何让JMX绑定到特定的接口?

在我们的环境中,经常会有同时在一台机器上运行多个Java VM的情况。尽管可以告诉JMX在不同的TCP端口上侦听(使用com.sun.management.jmxremote.port),但如果让JMX使用标准的JMX端口并绑定到特定的IP地址(而不是所有的IP地址),那将是一件好事。

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

回答

8

费尔南多已经提供了一个链接到my blog post :) ..它不是微不足道的。您必须提供您自己的RMIServerSocketFactoryImpl,以在想要的地址上创建套接字。

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

+0

谢谢 - 我没有认为它会简单或漂亮。 :) – 2008-12-02 06:53:09

-3

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

-Djava.rmi.server.hostname=<YOUR_IP> 

...还有...

-Dcom.sun.management.jmxremote.host=<YOUR_IP> 

但是,至少在我的系统下JDK 1.7,这些似乎没有任何效果 - JMX连接器仍然绑定到*。更新的答案(具体适用版本)将不胜感激。这应该是简单的。

+0

这些都不控制绑定地址。 `java.rmi.server.hostname`并不是新的,它已经存在17年了,我怀疑另一个是新的。 – EJP 2014-09-16 00:46:36

+0

我没有说他们是新的。我说我看过他们,他们没有工作。 – sosiouxme 2014-09-16 16:41:40

0

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

这里的主要问题是,没有简单的方法来指定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/ 文件夹中。

然后,您需要将下面一行添加到斌/ setenv.sh:

CLASSPATH = $ CLASSPATH:$ CATALINA_HOME/lib目录/ mx_patch。罐子

添加在Tomcat实例此选项启动

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

这将仅绑定JMX服务来解决192.168.100.100。其他2个 随机RMI监听端口仍然会绑定到所有的接口,但这很好 ,因为他们总是挑一个自由港反正。

现在,您可以与所有的 默认端口一台主机上运行多个Tomcat实例完好无损(例如8080 for JMX for 他们全部)。

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); 
    } 

}

0

我只是想

-Dcom.sun.management.jmxremote.host =

与OpenJDK的1.8,它运作良好。它绑定到那个地址(根据netstat),并且所有看起来都正确(和工作)。