有没有人让远程 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=添加 -Djava.rmi.server.hostname='<host ip>'
为我解决了这个问题。
【讨论】:
就我而言,我必须添加 ip 地址 (-Djava.rmi.server.hostname=尝试使用 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 <JMX_port>:localhost:<JMX_port> <remote_user>@<remote_host>
(3)然后我连接到远程 JMX 使用:jconsole <remote_host>:<JMX_port>
【参考方案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 工作?的主要内容,如果未能解决你的问题,请参考以下文章