我有一个解决方案:
如果您的Java进程在Linux防火墙后运行,并且您想要在Windows本地机器上启动JConsole / Java VisualVM / Java Mission Control来连接到您的Java进程的JMX端口。
您需要通过SSH登录访问Linux机器。所有通信都将通过SSH连接进行隧道传输。
TIP: 无论是否有防火墙,此解决方案均有效。
缺点:每次重新启动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进程的进程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存根。此端口还需要通过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
![使用Putty打开SSL隧道的设置](https://istack.dev59.com/CHa4j.webp)
7. 使用启用了SSH隧道的Putty登录到您的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. 启动 JConsole / Java VisualVM / Java Mission Control 并使用以下 URL 连接到您的 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
![通过JMX服务URL连接](https://istack.dev59.com/QnfvI.webp)
9. ENJOY #8-]