有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

基于ssh的java JConsole本地端口转发

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

有没有办法让jconsole只通过9999连接或使用代理?是this article still the best solution吗?还是我错过了什么


共 (4) 个答案

  1. # 1 楼答案

    Is there any way to make jconsole only connect through 9999 or use a proxy? Is this article still the best solution? Or, am I missing something?

    是的,那篇文章是关于正确的

    在服务器上指定JMX端口(-Dcom.sun.management.jmxremote.port=####)时,实际上是在指定应用程序的注册表端口。连接时,它会提供一个额外的服务器端口,jconsole实际上会使用该端口执行所有工作。要转发到工作中,您需要同时了解注册表和服务器端口

    在注册表和服务器端口都设置为8000的情况下运行应用程序时,应该可以使用以下类似的方法。见here for more details

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

    另外,my SimpleJMX library允许您轻松设置两个端口,并且可以将它们设置为同一个端口

    因此,一旦知道需要转发的两个端口,就可以设置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
    
  2. # 2 楼答案

    有一种更好的方法可以使用SSH socks隧道实现这一点,因为JConsole支持socks:

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

      ssh -fN -D 7777 user@firewalled-host

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

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

    正如下面的一个答案所提到的,在JDK 8u60+中,您还需要有-J-DsocksNonProxyHosts=选项才能使其工作

  3. # 3 楼答案

    几乎所有当前的JDK版本(7u25或更高版本)现在都可以通过SSH非常轻松地使用JConsole和可视化JVM(because now you can bind JMX to single port

    我使用以下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连接之后

    Remote Process: -> localhost:8090

    和Java Visual VM

    Right Click on Local -> Add JMX Connection -> localhost:8090

  4. # 4 楼答案

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

    jconsole -J-DsocksProxyHost=localhost -J-DsocksProxyPort=7777 -J-DsocksNonProxyHosts=