68

我希望能够远程连接到暴露了 JMX 的 Java 服务,但是它被防火墙阻止了。我尝试使用 ssh 本地端口转发,但是连接失败。查看wireshark,似乎当您尝试与jconsole连接时,它希望在连接到端口9999后通过一些临时端口进行连接,这些端口被防火墙阻止。

有没有办法让 jconsole 只通过 9999 连接或使用代理?这篇文章仍然是最好的解决方案吗?或者,我错过了什么?

4

4 回答 4

118

由于 JConsole 支持 SOCKS,因此使用 SSH socks 隧道有更好的方法:

  1. 在某个空闲端口(例如 7777)上本地创建 SSH socks 代理:

    ssh -fN -D 7777 用户@防火墙主机

  2. 通过指定 SOCKS 代理(例如 localhost:7777)和 JMX 服务器的地址(例如 localhost:2147)来运行 JConsole

    jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=7777 服务:jmx:rmi:///jndi/rmi://localhost:2147/jmxrmi -J-DsocksNonProxyHosts=

如以下答案之一所述,从 JDK 8u60+ 开始,您还需要-J-DsocksNonProxyHosts=选择才能使其正常工作。

于 2013-10-31T12:13:33.117 回答
67

对于几乎所有当前的 JDK 版本(7u25 或更高版本),现在可以很容易地通过 SSH 使用 JConsole 和 Visual JVM(因为现在您可以将 JMX 绑定到单端口)。

我使用以下 JVM 参数

-Dcom.sun.management.jmxremote.port=8090
-Dcom.sun.management.jmxremote.rmi.port=8090
-Djava.rmi.server.hostname=127.0.0.1
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

然后我启动 SSH 连接

ssh my.javaserver.domain -L 8090:127.0.0.1:8090

在我可以从 JConsole 连接之后

远程进程:-> localhost:8090

和 Java Visual VM

右键单击本地 -> 添加 JMX 连接 -> localhost:8090

于 2015-09-06T00:11:35.277 回答
42

有没有办法让 jconsole 只通过 9999 连接或使用代理?这篇文章仍然是最好的解决方案吗?或者,我错过了什么?

是的,那篇文章是对的。

当您在服务器上指定 JMX 端口 ( -Dcom.sun.management.jmxremote.port=####) 时,实际上您只是指定了应用程序的注册表端口。当你连接它时,它会提供一个额外的服务器端口,jconsole 实际上会使用它来完成所有工作。要转发工作,您需要知道注册表服务器端口。

在注册表和服务器端口都设置为 8000 的情况下,类似以下内容应该可以运行您的应用程序。有关详细信息,请参见此处

-Dcom.sun.management.jmxremote.port=8000
-Dcom.sun.management.jmxremote.rmi.port=8000
-Djava.rmi.server.hostname=127.0.0.1

顺便说一句,我的SimpleJMX 库允许您轻松设置两个端口,并且您可以将它们都设置为同一个端口。

因此,一旦您知道需要转发的两个端口,您就可以设置您的ssh命令。例如,如果您将注册表和服务器端口配置为 8000,您将执行以下操作:

ssh -L 8000:localhost:8000 remote-host

这将创建一个本地端口 8000,该端口转发到远程主机上的 localhost:8000。-L如果需要转发多个端口,可以指定多个参数。然后你可以将你的 jconsole 连接到 localhost:8000 ,它将适当地连接到远程主机。

此外,如果您的服务器有多个接口,您可能需要将java.rmi.server.hostname变量设置为绑定到正确的接口。

-Djava.rmi.server.hostname=10.1.2.3
于 2013-02-26T16:11:51.190 回答
13

继续使用 SSH socks 方法,使用较新的 java 版本(大约 8u66),您还需要将 socksNonProxyHosts 设置为空,从而导致:

jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=7777 -J-DsocksNonProxyHosts=
于 2015-08-26T15:22:58.613 回答