2011-03-21 63 views
3

我有很多jconsole.exe和JVisualVM.exe的经验,在JDK1.6中已经连接了数千次从Windows JVM到通过JMX.remote在另一台机器上运行Windows JVM,但当我尝试监视在Linux主机上运行的Java实例(来自Windows主机,并且我在Amazon EC2上尝试了Redhat和SUSE上的JMX侦听器)时失败。我也尝试使用jconsole.exe并得到类似的错误。JMX:无法从Windows连接到监视Linux系统上的JMX端口

有什么理由可以想到为什么这种JMX连接会有问题。任何想法,我可以尝试?有没有人“真的”做到这一点,并可以说,如果我坚持下去,它会工作?

我从JVisualVM获得(在远程连接尝试)错误是这样的:

"Cannot connect using service:jmx:rmi:///jndi/rmi://<jmx service ip>:8001/jmxrmi" 

我的远程JMX服务的配置是这样的:

-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=8001 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.hostname=<jmx service ip> 

发现在类似的问题this link但它没有回答我的问题。

我确认“iptables”没有启用作为服务,并且没有启动,所以我没有任何形式的防火墙阻止。另外,windows和linux机器都在一个10.0.0.0私有内部子网上。我能够远程登录到8001端口来验证它的存在,并在linux机器上侦听(netstat -ap)。

回答

6

查看系统属性java.rmi.server.hostname。在您的Linux服务器JVM上,将此系统属性设置为主机的公共IP。然后在您的客户端JMX URL中使用公共IP。

+0

指向java文档的链接已损坏 – harschware 2017-01-17 18:54:59

+1

对不起...更新后的链接。我猜没有人再使用Java 1.4了.... :) – Nicholas 2017-01-17 20:05:48

2

我认为你的问题是RMI的实现有点难以通过防火墙来工作,比如它需要比指定的端口更多的工作。如果您连接到自己的机器或同一网络上的一台机器,您通常不会注意的事情。 This post describes the problems you will run into quite well

如果我是你,我会尝试设置jmxmp作为替代协议。为此,您需要将jmxremote_optional.jar(从Oracle免费下载,请下载"JMX Remote API 1.0.1_04 Reference Implementation" from here)添加到服务器和jvisualvm类路径中,但这是值得的。

如果你是谷歌的jmxmp,你会发现很多关于如何设置的例子,我的第一个命中之一是http://pub.admc.com/howtos/jmx/distributed-chapt.html#jmxmp-sect,它可能有点过于面向代码,但无论如何我都在这里添加它,因为它解释了像最喜欢jmxmp的几句好句子。

如何定义服务器端端点取决于您正在运行的是什么。大多数应用程序服务器将允许您键入启用了jmxmp的jmx服务url,但如果服务器是从头开始编写的,则可能必须自己将其设置为代码,而不是使用-D开关转换为您习惯的java。

如果遇到问题,请尝试并返回更具体的问题。

编辑: 后您添加的jar到classpath,你有你的代码做的唯一的事情(你是不是使用已经处理它为你的服务器应用程序假设)如下(省略声明,异常处理以及诸如此类的问题):

url=new JMXServiceURL(jmxurl); 
this.server = JMXConnectorServerFactory.newJMXConnectorServer(url, null, ManagementFactory.getPlatformMBeanServer()); 
this.server.start(); 
+0

我核实,没有端口阻塞(如我上面我说的编辑),但我会看你的建议,并尽快给您答复。 – djangofan 2011-03-21 21:17:14

+1

问题是,验证您没有阻止指定的端口是不够的。还有更多(如第一个链接所述)。无论如何,它有可能得到它的工作,但jmxmp更容易合作,(imho)更好地远距离工作。 – Fredrik 2011-03-21 21:28:38

+0

我无法找到任何有关“-D”参数的文档,以便JVM获取JMXMP侦听器。或者,除非我用代码实现它,否则它不起作用,比如Jetty通过配置文件在代码中实现它的方式? – djangofan 2011-03-21 22:50:20

1

您是否尝试过从Windows计算机创建SSH隧道到Linux框?http://oldsite.precedence.co.uk/nc/putty.html

或者,如果你有cygwin的,只是尽量ssh -f [email protected] -L 7777:remote-server.com:123 -N其中7777是Windows计算机上的端口,123是在远程Linux机器侦听JMX命令的端口。

使用上述任一选项,您可以在Windows窗口中使用jconsole或visualvm并连接到localhost:7777

我知道iptables已禁用,但只需确认JMX在该端口工作正常,即通过SSH进入Linux机器并尝试将jconsole的命令行JMX模式用于localhost(在Linux机器上)。

+0

我使用Bitwise Tunnelier SSH客户端来设置客户端到服务器的端口转发。仍然无法使它工作,但我会摆弄它一些,因为它似乎有希望... – djangofan 2011-03-21 22:53:08

+0

要确认您的端口转发技术的工作原理,只是尝试使用它在远程服务器上,你知道工作的一些端口。就像运行在端口80上的Apache实例一样,您可以使用'curl http:// localhost'从该命令行访问该端口。一旦你知道这个端口能够工作,就尝试从你的windows中设置一个隧道/端口转发,然后看看你是否能够访问它。这样,您知道端口转发正在为您工作,并且可以将问题的范围限制到JMX服务器。 – domspawn 2011-03-22 11:43:51

0

我实际上刚刚自己解决了这个问题并想出了它。

我敢打赌,问题是RMI连接 - 你无法预测它将使用哪个端口,所以你不能让它与防火墙一起工作。

解决方法是使用SSH代理:

  1. SSH到您的应用程序正在运行,但这样使用-D选项框:

    SSH用户@ REMOTEHOST -D 9999

    当你在Windows上,你可以使用Cygwin运行上面的命令,或者您也可以通过GUI做腻子同样的事情(指导这里:http://blog.ashurex.com/2012/03/15/creating-ssh-proxy-tunnel-putty/

    这将启动一个socks代理在本地机器上的端口9999

  2. 打开JVisualVM和喜好,在“网络”配置为使用本地主机SOCKS代理,端口9999

如果你这样做,你应该能够像往常一样连接到远程机器,并且由于所有的RMI流量现在都在通过SSH代理进行传输,所以它是通过防火墙穿透并且很好地工作的。

好运:-)