123

It seems that I've never got this to work in the past. Currently, I KNOW it doesn't work.

But we start up our Java process:

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

I can telnet to the port, and "something is there" (that is, if I don't start the process, nothing answers, but if I do, it does), but I can not get JConsole to work filling in the IP and port.

Seems like it should be so simple, but no errors, no noise, no nothing. Just doesn't work.

Anyone know the hot tip for this?

4

20 回答 20

129

我有一个解决方案:

如果您的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 stubs下载的任意端口

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 机器上使用 putty 启用两个 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 会话保持打开状态。

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

JMX-端口:

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

RMIServer 存根端口:

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 机器上的端口。但是腻子将所有有效负载发送到端口 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 连接


9.享受#8-]

于 2013-07-03T20:19:20.100 回答
80

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

于 2009-05-22T21:08:17.720 回答
65

尝试使用 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 隧道,有助于避免防火墙或各种网络问题。

于 2015-11-24T11:47:16.180 回答
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 隧道并让它继续工作:-)

于 2008-12-12T14:45:44.147 回答
18

在过去几天对我的 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

我没有看到任何 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)
于 2014-12-16T19:10:07.237 回答
11

你在 Linux 上运行吗?也许管理代理绑定到本地主机:

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

于 2008-09-30T03:13:08.080 回答
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 连接使用隧道。否则它可能会尝试直接连接并击中防火墙。

于 2016-04-08T12:18:04.010 回答
6

专家提示:

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

您需要修复(如拥有一个已知编号)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> \

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

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

service:jmx:rmi://<hostname>:10002/jndi/rmi://<hostname>:10001/jmxrmi
于 2013-10-11T09:48:12.753 回答
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"
于 2015-06-04T06:37:08.387 回答
4

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

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

  1. JMX over SSH Tunnel 和 Socks 代理,使用标准 RMI 和 SSH 魔术 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

于 2013-06-17T07:34:45.070 回答
2

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

于 2008-12-12T14:17:21.570 回答
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
    
于 2015-01-27T09:31:36.807 回答
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,但我认为这不是问题,因为即使防火墙打开,我也可以远程登录到 2100。希望能帮助到你。

于 2018-10-10T07:56:06.747 回答
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 设置的用于远程管理的端口号。

于 2010-07-15T13:57:17.093 回答
1

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

  • 添加-Djava.rmi.server.hostname=192.168.59.103
  • 在主机和 docker 容器中使用相同的 JMX 端口,例如:docker run ... -p 9999:9999 .... 使用不同的端口不起作用。
于 2015-05-29T08:11:56.353 回答
0

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

于 2013-08-26T23:44:58.683 回答
0

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

于 2013-03-28T15:46:59.913 回答
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 步中的所有端口

瞧。

于 2015-02-10T20:22:39.970 回答
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

这终于为我做到了。

于 2016-12-22T00:21:46.167 回答
0

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

  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 进行连接。

于 2015-09-23T20:22:42.927 回答