有没有人让远程 JMX JConsole 工作?

Posted

技术标签:

【中文标题】有没有人让远程 JMX JConsole 工作?【英文标题】:Has anyone ever got a remote JMX JConsole to work? 【发布时间】:2010-09-14 03:42:02 【问题描述】:

看来我过去从来没有这样工作过。目前,我知道它不起作用。

但是我们启动了我们的 Java 进程:

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

我可以远程登录到端口,并且“有东西”(也就是说,如果我不启动该进程,则没有任何响应,但如果我启动,它会响应),但我无法让 JConsole 工作填充在 IP 和端口中。

似乎应该如此简单,但没有错误,没有噪音,什么都没有。就是不行。

有人知道这方面的热点提示吗?

【问题讨论】:

如果您使用的是 tomcat,这可能是解决方案:***.com/questions/1263991/… 你是不是忘记在这里接受@Will 的东西? 【参考方案1】:

我有一个解决方案:

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

您需要通过 SSH 登录来访问您的 linux 机器。所有通信都将通过 SSH 连接进行隧道传输。

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

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

1。您需要从这里为您的 Windows 机器安装 putty-suite:

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 进程的 Process-Id

ps -ef | grep <java-processname>

result ---> <process-id>

示例:

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

result ---> 24321

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

java 进程在 linux 机器上打开一个新的 TCP 端口,RMI 服务器存根将在该端口可供下载。此端口还需要通过 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。使用 putty 从您的 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

7.使用 Putty 并启用此 SSH 隧道登录到您的 Linux 机器。

让 putty 会话保持打开状态。

登录后,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。使用以下 URL 启动 JConsole / Java VisualVM / Java Mission Control 以连接到您的 Java 进程

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

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

然后 JConsole / Java VisualVM / Java Mission Control 认为它连接到 localhost:37123 并且 putty 会将整个有效负载转发到 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

9。享受#8-]

【讨论】:

这里只是一个小问题 - 没有 rmi 就无法建立 JMX 连接? 我得到一个提示,我们可以将一个 rmi.port 设置为一个固定的端口号,这样我们就可以为 RMIServer 存根下载设置任意端口。这应该适用于 Java 属性“com.sun.management.jmxremote.rmi.port=”。它看起来像是 Oracle Java VM 中未记录的特性。 肯定比设置密钥库和受信任的存储要好 相同的过程,但我在表中没有这样的对象 @sushicutta 你能在你的答案中添加这个提示吗,它工作得很好,并且可以删除从 4 到 6 的步骤,问题是你的转发端口必须与原始端口相同,并且jmx 和 rmi 端口也必须相同【参考方案2】:

添加 -Djava.rmi.server.hostname='&lt;host ip&gt;' 为我解决了这个问题。

【讨论】:

就我而言,我必须添加 ip 地址 (-Djava.rmi.server.hostname=)。 hostname -i 给了我两个 IP 地址,正确的一个在列表中的第二个。 没有为我解决问题。连接 windows-2-windows 对我来说不是问题,但是当我尝试从 Windows 上的 JVM Jvisualvm.exe 连接以监视使用 Oracle JDK 1.6.024 在 SUSE 上运行的 java 服务时,连接失败。出于这个原因,我认为这个人的问题仍然没有答案。 这为我解决了这个问题。这加上通常的 3 (authenticate/port/ssl) 集,我现在可以远程连接。虽然该框正在侦听多个虚拟接口,但可能是为什么不指定主机会混淆 jvm。 终于解决了我在 osx 笔记本电脑上连接 jconsole 的问题。谢谢。 为我工作。谢谢!【参考方案3】:

尝试使用 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。玩得开心!

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

【讨论】:

Oracle 没有提及“com.sun.management.jmxremote.rmi.port”、“java.rmi.server.hostname”docs.oracle.com/javase/8/docs/technotes/guides/management/… 真的很糟糕,我想这是我的问题。跨度> 因为,AFAIK,这个问题不在于 JMX,而在于 RMI 是如何工作的。例如,在这个案例之后,我在使用 jmeter 时遇到了同样的问题,它在其客户端/服务器实现中使用了 rmi。 它有效。只需添加我对隧道的经验:1)可以在“-L 1616:localhost:1616”中使用“localhost” 2)不能更改源端口,即这不起作用:“-L 9999:localhost:1616” 是否有理由选择 JConsole 而不是 Java VisualVM / Java Mission Control? 您应该补充一点,putty.exe -ssh user@remote-host -L 1616:remote-host:1616 将打开一个腻子窗口,询问您的密码,然后它不会发生任何事情,但它应该保持打开状态 :)【参考方案4】:

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

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

有一个不需要打开很多端口的解决方案,但是,我已经使用组合源 sn-ps 和提示来自

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 隧道并让它继续工作:-)

【讨论】:

我只能使用simplygenius.com/2010/08/jconsole-via-socks-ssh-tunnel.html 中描述的别名以及此处另一个答案中提到的 -Djava.rmi.server.hostname 设置来绕过防火墙。 未来读者请注意:forums.sun.com 的链接已损坏 未来读者请注意:blogs.oracle.com 的链接已损坏。【参考方案5】:

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

从戴尔 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

我没有看到任何 Stack Overflow 答案封面的一行是

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

就我而言,我试图检索 Kafka 指标,因此我只是更改了上述选项以匹配 -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)

【讨论】:

加一个“Google-fu” "com.sun.management.jmxremote.rmi.port" 对我来说也是关键。另请参阅此答案:***.com/a/22306586/123205 我不需要“com.sun.management.jmxremote.local.only”所以我不认为你的配置是真正的“最低限度”【参考方案6】:

您在 Linux 上运行吗?也许管理代理绑定到 localhost:

http://java.sun.com/j2se/1.5.0/docs/guide/management/faq.html#linux1

【讨论】:

【参考方案7】:

Sushicutta 的步骤 4-7 可以通过在步骤 3 中添加以下行来跳过:

-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>

请注意,需要 hostname=localhost 以确保 jmxremote 告诉 rmi 连接使用隧道。否则它可能会尝试直接连接并击中防火墙。

【讨论】:

这个方法对我有帮助:(1)我添加错过的 JMX 参数并重新启动应用程序(2)然后在本地机器上运行 ssh -L &lt;JMX_port&gt;:localhost:&lt;JMX_port&gt; &lt;remote_user&gt;@&lt;remote_host&gt;(3)然后我连接到远程 JMX 使用:jconsole &lt;remote_host&gt;:&lt;JMX_port&gt; 【参考方案8】:

提示:

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

您需要修复(如拥有一个已知编号)RMI 注册表和 JMX/RMI 服务器端口。为此,您可以在 lib-dir 中放置一个 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> \

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

然后你可以使用这个可怕的 URL 进行连接:

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

【讨论】:

用 extras jar 尝试了上面的方法,可以看到 RMI 端口按指定的方式监听,但是在使用 VisualVM 连接到 JVM 端口后,RMI 仍然使用随机端口。解决方法:监视带有“lsof -i”的端口并打开那些连接被阻止的端口。【参考方案9】:

检查您的服务器是否位于防火墙后面。 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"

【讨论】:

【参考方案10】:

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

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

    JMX over SSH 隧道和 Socks 代理,使用标准 RMI 和 SSH 魔法 http://simplygenius.com/2010/08/jconsole-via-socks-ssh-tunnel.html

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

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

【讨论】:

所有其他答案都应该是这个答案的补充【参考方案11】:

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

【讨论】:

【参考方案12】:

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

sushicutta 的方法很好,但是非常手动,因为您每次都必须获取 RMI 端口。值得庆幸的是,我们可以通过使用 SOCKS 代理而不是显式打开端口隧道来解决这个问题。这种方法的缺点是您在机器上运行的 JMX 应用程序需要能够配置为使用代理。大多数进程都可以通过添加 java 属性来做到这一点,但是,有些应用程序不支持这一点。

步骤:

    将 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
    

    设置到远程计算机的 SOCKS 代理连接:

    ssh -D 9696 user@remotemachine.com
    

    配置您的本地 Java 监控应用程序以使用 SOCKS 代理 (localhost:9696)。注意:您可以有时从命令行执行此操作,即:

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

【讨论】:

【参考方案13】:

以下内容对我有用(尽管我认为 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,但我认为这不是问题,因为即使防火墙打开,我也可以远程登录到 2100。 希望对您有所帮助。

【讨论】:

【参考方案14】:

我在 windows 上运行 JConsole/JVisualVm,​​连接到运行 Linux Redhat ES3 的 tomcat。

使用以下命令禁用数据包过滤对我有用:

/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 设置的用于远程管理的端口号。

【讨论】:

在 SUSE Amazon EC2 实例上对我不起作用。我认为问题出在其他地方。【参考方案15】:

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

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

【讨论】:

【参考方案16】:

您还需要确保您的机器名称解析为 JMX 绑定的 IP;不是本地主机也不是 127.0.0.1。对我来说,它有助于将一个条目放入明确定义它的主机中。

【讨论】:

【参考方案17】:

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

【讨论】:

【参考方案18】:

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

检查服务器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 步中的所有端口

瞧。

【讨论】:

【参考方案19】:

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

    关闭 iptables 服务

    service iptables stop
    

    将以下行添加到 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 进行连接。

【讨论】:

【参考方案20】:

我正在尝试让 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

这终于为我做到了。

【讨论】:

以上是关于有没有人让远程 JMX JConsole 工作?的主要内容,如果未能解决你的问题,请参考以下文章

使用 visualvm 和 JMX 进行远程监控

JConsole 远程连接到 JBoss EAP

JConsole的设置及远程连接

JMV监控工具之JConsole

Jconsole

远程连接JMX出现问题