2008-12-01 43 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),並且所有看起來都正確(和工作)。

相關問題