有没有人可以使用远程JMX JConsole来工作?


120

看来我过去从未做到这一点。目前,我知道它不起作用。

但是,我们启动了Java流程:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=6002
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

我可以通过telnet到端口,并且“有东西”(也就是说,如果我不启动该进程,则没有任何答案,但是如果我这样做,则可以),但是我无法让JConsole填写IP和港口。

似乎应该这么简单,但是没有错误,没有噪音,什么也没有。只是不起作用。

有人知道这个热门提示吗?


3
如果使用Tomcat这样的youre可能是解决办法: stackoverflow.com/questions/1263991/...
哈乔Thelen

5
你忘了在@Will这里接受吗?
2014年

Answers:


126

我对此有一个解决方案:

如果Java进程在防火墙后面的Linux上运行,并且您想在本地计算机上的Windows上启动JConsole / Java VisualVM / Java Mission Control,以将其连接到Java进程JMX端口

您需要通过SSH登录访问Linux计算机。所有通信将通过SSH连接建立隧道。

提示:无论是否有防火墙,此解决方案均有效。

缺点:每次重新启动 Java进程时,都需要再次执行4-9的所有步骤。


1.您需要从以下位置为Windows机器安装腻子套件:

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

至少是putty.exe


2.在您的linux机器上定义一个空闲端口:

<jmx-remote-port>

例:

jmx-remote-port = 15666      


3.在Linux机器上向Java进程添加参数

这必须完全像这样完成。如果按以下方式进行操作,则它适用于防火墙后的linux计算机(它是引起该-Djava.rmi.server.hostname=localhost问题的原因)。

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=<jmx-remote-port>
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

例:

java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=15666 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=false -Djava.rmi.server.hostname=localhost ch.sushicutta.jmxremote.Main


4.获取您的Java进程的进程ID

ps -ef | grep <java-processname>

result ---> <process-id>

例:

ps -ef | grep ch.sushicutta.jmxremote.Main

result ---> 24321


5.查找RMIServer存根下载的任意端口

Java进程在linux机器上打开一个新的TCP端口,RMI Server-Stubs将在此下载。还需要通过SSH隧道提供此端口,以建立与Java虚拟机的连接。

使用netstat -lp此端口,还可以lsof -i提示从Java进程打开了哪个端口。

注意:启动Java进程时,此端口始终更改。

netstat -lp | grep <process-id>

tcp        0      0 *:<jmx-remote-port>     *:*     LISTEN      24321/java
tcp        0      0 *:<rmi-server-port>     *:*     LISTEN      24321/java


result ---> <rmi-server-port>

例:

netstat -lp | grep 24321

tcp        0      0 *:15666     *:*     LISTEN      24321/java
tcp        0      0 *:37123     *:*     LISTEN      24321/java


result ---> 37123


6.用腻子在Windows机器上启用两个SSH隧道

Source port: <jmx-remote-port>
Destination: localhost:<jmx-remote-port>
[x] Local       
[x] Auto       

Source port: <rmi-server-port>
Destination: localhost:<rmi-server-port>
[x] Local       
[x] Auto

例:

Source port: 15666
Destination: localhost:15666
[x] Local       
[x] Auto       

Source port: 37123
Destination: localhost:37123
[x] Local       
[x] Auto


通过Putty打开SSL隧道的设置


7.在启用了此SSH隧道的情况下,使用Putty登录到Linux计算机。

保持腻子打开状态。

登录后,Putty将通过SSH端口22将所有TCP连接通过隧道传输到linux计算机。

JMX端口:

Windows machine: localhost:15666   >>> SSH >>>   linux machine: localhost:15666

RMIServer-Stub-Port:

Windows Machine: localhost:37123   >>> SSH >>>   linux machine: localhost:37123


8.启动JConsole / Java VisualVM / Java Mission Control,以使用以下URL连接到Java进程

这可行,因为JConsole / Java VisualVM / Java Mission Control认为您已连接到本地Windows计算机上的端口。但是Putty将所有负载发送到Linux机器的端口15666。

首先在linux机器上,java进程给出答案并发回RMIServer端口。在此示例37123。

然后JConsole / Java VisualVM / Java Mission Control认为它已连接到localhost:37123,而腻子会将整个有效负载发送到linux机器

Java进程回答并且连接已打开。

[x] Remote Process:
service:jmx:rmi:///jndi/rmi://localhost:<jndi-remote-port>/jmxrmi

例:

[x] Remote Process:
service:jmx:rmi:///jndi/rmi://localhost:15666/jmxrmi


通过jmx服务网址连接


9.享受#8-]


1
这里只是一个小问题-没有rmi不可能建立JMX连接吗?
Kumar Vaibhav '02

5
我得到了一个提示,我们可以将rmi.port设置为固定的端口号,因此可以为RMIServer存根下载设置任意端口。这应该与Java属性“ com.sun.management.jmxremote.rmi.port = <rmi-server-port>”一起使用。它看起来像Oracle Java VM中未记录的功能。
sushicutta 2015年

1
肯定需要设置密钥库和
受信任的

相同的过程,但是表中没有这样的对象
较慢,2015年

2
@sushicutta您可以在答案中添加此提示吗,它的工作原理非常好,并且可以删除第4步到第6步,发现您转发的端口必须与原始端口相同,并且jmx和rmi端口也必须一样
破旧的

80

添加-Djava.rmi.server.hostname='<host ip>'为我解决了这个问题。


2
就我而言,我必须添加IP地址(-Djava.rmi.server.hostname = <ip>)。主机名-i给了我两个IP地址,正确的IP地址是列表中的第二个。
Georgy Bolyuba,2009年

4
没有为我解决问题。但是,当我尝试从Windows上的JVM Jvisualvm.exe连接以监视在Oracle JDK 1.6.024上在SUSE上运行的Java服务时,连接Windows-2-windows对我来说不是问题,但连接失败。因此,我认为这个人的问题仍然没有答案。
djangofan 2011年

这为我解决了这个问题。这加上通常的3个(验证/端口/ ssl)设置,我现在可以远程连接了。虽然该框正在侦听多个虚拟接口,但这可能就是为什么不指定混淆了jvm的主机的原因。
Nicholi

终于解决了我在osx笔记本电脑上连接jconsole的问题。谢谢。
拉多

为我工作。谢谢!
杰夫,

58

尝试过Java 8和更高版本

该解决方案也适用于防火墙

1.将其添加到远程主机上的Java启动脚本中:

-Dcom.sun.management.jmxremote.port=1616
-Dcom.sun.management.jmxremote.rmi.port=1616
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

2.在计算机上执行此操作。

  • Windows用户

    putty.exe -ssh user@remote-host -L 1616:remote-host:1616

  • Linux和Mac用户

    ssh user@remote-host -L 1616:remote-host:1616

3. jconsole在电脑上启动

jconsole localhost:1616

4.玩得开心!

PS:在第2步中,使用ssh-L指定必须将本地(客户端)主机上的端口1616转发到远程端。这是一个ssh隧道,有助于避免防火墙或各种网络问题。


1
太棒了!! 现在已经尝试了6个多小时,以将jmx远程迁移到java8上的ActiveMQ实例。终于奏效了!!谢谢!:)
Rop

谢谢,像你一样,我也挣扎了一天,经过这么多的工作,我只是想:“我必须把这个东西写成这样!”
freedev

2
真的很烂,甲骨文并没有提到“com.sun.management.jmxremote.rmi.port”,“java.rmi.server.hostname” docs.oracle.com/javase/8/docs/technotes/guides/management/... 我猜那是我的问题。
Rop

因为,对于AFAIK,此问题不关乎JMX,而是RMI的工作方式。例如,在这种情况下,我遇到了jmeter的相同问题,它在客户端/服务器实现中使用rmi。
freedev

2
有用。仅添加我在隧道上的经验:1)可以在“ -L 1616:localhost:1616”中使用“ localhost” 2)无法更改源端口,即,这将不起作用:“-L 9999:localhost:1616”
gargii

19

您可能遇到防火墙问题。“问题”是您指定的端口不是唯一使用的端口,它为RMI使用了1个甚至2个以上的端口,并且这些端口可能已被防火墙阻止。

如果使用默认的RMI配置,则不会预先知道其中一个额外的端口,因此您必须打开大量端口-这可能不会使服务器管理员感到厌烦。

有一种解决方案不需要打开大量端口,但是,我已经使用组合的源代码片段和技巧来使其工作

http://forums.sun.com/thread.jspa?threadID=5267091-链接不再起作用

http://blogs.oracle.com/jmxetc/entry/connecting_through_firewall_using_jmx

http://java.sun.com/javase/6/docs/technotes/guides/management/agent.html

甚至有可能设置ssh隧道并使其正常工作:-)


2
我能够使用仅在simplegenius.com/2010/08/jconsole-via-socks-ssh-tunnel.html中描述的别名以及设置-Djava.rmi.server.hostname 来解决防火墙,如此处另一个答案所述。
达米安

未来的读者请注意:链接forums.sun.com已断开
CDspace

1
注意事项:链接blogs.oracle.com已断开。
Grimlock

17

在过去几天对Google-fu进行了测试之后,在从Stack Overflow和本页http://help.boomi.com/atomsphere/GUID-F787998C-上编译了答案之后,我终于能够使它工作。 53C8-4662-AA06-8B1D32F9D55B.html

从Dell Boomi页面重新发布:

To Enable Remote JMX on an Atom

If you want to monitor the status of an Atom, you need to turn on Remote JMX (Java Management Extensions) for the Atom.

Use a text editor to open the <atom_installation_directory>\bin\atom.vmoptions file.

Add the following lines to the file:

-Dcom.sun.management.jmxremote.port=5002
-Dcom.sun.management.jmxremote.rmi.port=5002
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

我没有看到任何堆栈溢出答案封面的那一行是

-Dcom.sun.management.jmxremote.rmi.port=5002

就我而言,我试图检索Kakfa指标,因此我只是更改了上述选项以匹配该-Dcom.sun.management.jmxremote.port值。因此,没有任何形式的身份验证,最低限度的最低配置应如下所示:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=(jmx remote port)

-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=(jmx remote port)
-Djava.rmi.server.hostname=(CNAME|IP Address)

1
加一个“ Google-fu”
kevinarpe 2015年

“ com.sun.management.jmxremote.rmi.port”也是我的关键。另请参阅以下答案:stackoverflow.com/a/22306586/123205
David David

我不需要“ com.sun.management.jmxremote.local.only”,因此我认为您的配置不是真正的“裸机”
David


7

将以下行添加到步骤3,可以跳过Sushicutta的步骤4-7:

-Dcom.sun.management.jmxremote.rmi.port=<same port as jmx-remote-port>

例如,添加以启动参数:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=12345
-Dcom.sun.management.jmxremote.rmi.port=12345
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.local.only=false
-Djava.rmi.server.hostname=localhost

对于端口转发,请使用以下命令进行连接:

ssh -L 12345:localhost:12345 <username>@<host>

如果您的主人是垫脚石,只需在上面的垫脚石上运行以下命令,即可将端口向前链接:

ssh -L 12345:localhost:12345 <username>@<host2>

请注意,需要主机名= localhost来确保jmxremote告诉rmi连接使用隧道。否则,它可能会尝试直接连接并进入防火墙。


此方法对我有帮助:(1)添加丢失的JMX参数并重新启动应用程序(2)然后ssh -L <JMX_port>:localhost:<JMX_port> <remote_user>@<remote_host> 在本地计算机上运行 (3)然后使用以下方法连接到远程JMX: jconsole <remote_host>:<JMX_port>
Rib47

6

专家提示:

RMI端口在任意portnr处打开。如果您有防火墙并且不想打开端口1024-65535(或使用vpn),则需要执行以下操作。

您需要修复(如具有已知编号)RMI注册表和JMX / RMI服务器端口。您可以通过在jar目录中放置一个jar文件(catalina-jmx-remote.jar在附加文件中)并在服务器下配置一个特殊的侦听器来做到这一点:

<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener"
      rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />

(当然还有激活JMX的常用标志

    -Dcom.sun.management.jmxremote  \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Dcom.sun.management.jmxremote.authenticate=false \
    -Djava.rmi.server.hostname=<HOSTNAME> \

请参阅:http://tomcat.apache.org/tomcat-6.0-doc/config/listeners.html上的 JMX远程生命周期侦听器

然后,您可以使用以下可怕的URL进行连接:

service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>:10001/jmxrmi

尝试了上述w / extras jar,可以看到RMI端口正在按指定侦听,但是在使用VisualVM连接到JVM端口后,RMI仍使用随机端口。解决方法:使用“ lsof -i”监视端口,并打开连接被阻塞的端口。
约瑟夫·拉斯特

5

检查您的服务器是否在防火墙后面。JMX基于RMI,它在启动时会打开两个端口。一个是寄存器端口,默认为1099,可以由该com.sun.management.jmxremote.port选项指定。另一个用于数据通信,并且是随机的,这是导致问题的原因。一个好消息是,从JDK6开始,该随机端口可以由com.sun.management.jmxremote.rmi.port选项指定。

export CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8991 -Dcom.sun.management.jmxremote.rmi.port=8991 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

4

通过防火墙获取JMX确实很困难。问题在于标准RMI使用了第二个随机分配的端口(在RMI注册表旁边)。

我们有三种可行的解决方案,但是每种情况都需要一个不同的解决方案:

  1. 带有Socks代理的SSH隧道上的JMX,通过SSH魔术使用标准RMI http://simplygenius.com/2010/08/jconsole-via-socks-ssh-tunnel.html

  2. JMX MP(替代标准RMI),仅使用一个固定端口,但在服务器和客户端上需要一个特殊的jar http://meteatamel.wordpress.com/2012/02/13/jmx-rmi-vs-jmxmp/

  3. 启动JMX Server表单代码,可以使用标准RMI并使用第二个固定端口:https : //issues.apache.org/bugzilla/show_bug.cgi?id=39055


所有其他答案应该是这个答案的补充
ruruskyi 2015年

2

在测试/调试/诊断远程 JMX问题时,首先始终尝试连接包含MBeanServer的同一主机(即localhost),以排除网络和其他非JMX特定问题。


2

这里已经有了一些很好的答案,但是,我认为有一个稍微简单的方法值得分享。

sushicutta的方法很好,但是非常手工,因为您每次都必须获得RMI端口。幸运的是,我们可以通过使用SOCKS代理而不是显式打开端口隧道来解决此问题。这种方法的缺点是您需要在计算机上运行的JMX应用程序能够配置为使用代理。您可以通过添加Java属性来执行大多数过程,但是某些应用程序不支持此操作。

脚步:

  1. 将JMX选项添加到远程Java服务的启动脚本中:

    -Dcom.sun.management.jmxremote=true
    -Dcom.sun.management.jmxremote.port=8090
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.authenticate=false
    
  2. 设置到远程计算机的SOCKS代理连接:

    ssh -D 9696 user@remotemachine.com
    
  3. 将本地Java监视应用程序配置为使用SOCKS代理(localhost:9696)。注意:有时您可以从命令行执行此操作,即:

    jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=9696
    

2

以下内容对我有用(尽管我认为端口2101对此没有真正的贡献):

-Dcom.sun.management.jmxremote.port=2100
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=2101
-Djava.rmi.server.hostname=<IP_ADDRESS>OR<HOSTNAME>

我正在从远程计算机连接到运行Docker且服务器位于容器内部的服务器。另外,我停止了firewallD,但我认为这不是问题,因为即使打开防火墙也可以telnet到2100。希望能帮助到你。


1

我在挂钩到运行Linux Redhat ES3的tomcat的Windows上运行JConsole / JVisualVm。

使用以下命令禁用数据包筛选对我有用:

/usr/sbin/iptables -I INPUT -s jconsole-host -p tcp --destination-port jmxremote-port -j ACCEPT

其中,jconsole-host是运行JConsole的主机名或主机地址,而jmxremote-port是为com.sun.management.jmxremote.port设置的用于远程管理的端口号。


2
在SUSE Amazon EC2实例上对我不起作用。我认为问题出在哪里。
djangofan 2011年

1

我正在使用boot2docker运行带有Tomcat的docker容器,但遇到了同样的问题,解决方案是:

  • -Djava.rmi.server.hostname=192.168.59.103
  • 在主机和泊坞窗容器中使用相同的JMX端口,例如:docker run ... -p 9999:9999 ...。使用其他端口不起作用。

0

您还需要确保您的计算机名称解析为JMX绑定到的IP。不是localhost也不是127.0.0.1。对我来说,这有助于将条目放入明确定义此内容的主机中。


0

通过防火墙获取JMX一点都不困难。有一个小问题。您必须转发两个JMX配置的端口,即。9010和它在我的机器上侦听的动态端口之一> 30000


0

这些是对我有用的步骤(服务器端防火墙后的debian,是从本地Mac通过VPN到达的):

检查服务器IP

hostname -i

使用JVM参数:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=[jmx port]
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=[server ip from step 1]

运行应用程序

查找正在运行的Java进程的pid

检查JMX / RMI使用的所有端口

netstat -lp | grep [pid from step 4]

打开防火墙上第5步中的所有端口


0

为了做出贡献,这就是我在针对Tomcat 6的CentOS 6.4上所做的。

  1. 关机iptables服务

    service iptables stop
    
  2. 将以下行添加到tomcat6.conf

    CATALINA_OPTS="${CATALINA_OPTS} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8085 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=[host_ip]"
    

这样,我可以使用JConsole从另一台PC连接。


0

我正在尝试使用JMC运行Flight Recorder(JFR),以在不提供运行JMC的图形环境的远程服务器上对NiFi进行配置。

根据此处给出的其他答案以及经过反复试验的结果,这是我启动NiFi时提供给JVM(conf / bootstrap.conf)的内容:

java.arg.90=-Dcom.sun.management.jmxremote=true
java.arg.91=-Dcom.sun.management.jmxremote.port=9098
java.arg.92=-Dcom.sun.management.jmxremote.rmi.port=9098
java.arg.93=-Dcom.sun.management.jmxremote.authenticate=false
java.arg.94=-Dcom.sun.management.jmxremote.ssl=false
java.arg.95=-Dcom.sun.management.jmxremote.local.only=false
java.arg.96=-Djava.rmi.server.hostname=10.10.10.92  (the IP address of my server running NiFi)

我确实将此放在/ etc / hosts中,尽管我怀疑是否需要这样做:

10.10.10.92   localhost

然后,在启动JMC时,我创建具有以下属性的远程连接:

Host: 10.10.10.92
Port: 9098
User: (nothing)
Password: (ibid)

顺便说一句,如果单击“定制JMX服务URL”,则会看到:

service:jmx:rmi:///jndi/rmi://10.10.10.92:9098/jmxrmi

终于为我做到了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.