使用 visualvm 和 JMX 进行远程监控

Posted

技术标签:

【中文标题】使用 visualvm 和 JMX 进行远程监控【英文标题】:Remote monitoring with visualvm and JMX 【发布时间】:2015-07-16 04:06:27 【问题描述】:

我想使用 jvisualvm(或 jconsole)监控远程运行的 java(spring boot)应用程序。在本地运行时,我可以在 jvisualvm 和 jconsole 中看到托管 bean。远程运行时无法连接。我尝试了几个不同的 java 进程(例如使用 spring xd)。在 SO 和 Google 上寻找答案并没有帮助。

这些是我的 JAVA_OPTS(在远程主机上):

$ echo $JAVA_OPTS
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.59.99

然后我简单地启动程序如下(这是用于spring xd,但我在其他java程序中遇到同样的问题)。

$ bin/xd/xd-singlenode

服务器进程似乎选择了选项:

$ ps -ef | grep single
vagrant  22938 19917 99 06:38 pts/2    00:00:03 /usr/lib/jvm/java-8- oracle/jre/bin/java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=192.168.59.99 -Dspring.application.name=admin -Dlogging.config=file:/home/vagrant/spring-xd-1.1.0.RELEASE/xd/config///xd-singlenode-logger.properties -Dxd.home=/home/vagrant/spring-xd-1.1.0.RELEASE/xd -Dspring.config.location=file:/home/vagrant/spring-xd-1.1.0.RELEASE/xd/config// -Dxd.config.home=file:/home/vagrant/spring-xd-1.1.0.RELEASE/xd/config// -Dspring.config.name=servers,application -Dxd.module.config.location=file:/home/vagrant/spring-xd-1.1.0.RELEASE/xd/config//modules/ -Dxd.module.config.name=modules -classpath (...)

远程主机(ubuntu linux vm)上的java版本为:

$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

本地机器(Mac OS)上的java版本略有不同:

$ java -version    
java version "1.8.0_40"
Java(TM) SE Runtime Environment (build 1.8.0_40-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

在 jvisualvm 中,我按如下方式添加远程连接(尝试使用和不使用 ssl 连接):

这是 jvisualvm 给我的错误信息:

当远程进程正在运行时,我可以使用命令telnet 192.168.59.99:9010 从本地主机连接到远程主机——所以这似乎不是防火墙问题。

非常感谢任何帮助。

【问题讨论】:

您能否尝试以下 Java 选项:-"Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.authenticate= false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.59.99" 并且还在Jconsole中使用服务:jmx:rmi:///jndi/rmi://192.168.59.99 :9010/jmxrmi 你拯救了我的一天。这行得通。你能把这个作为答案发布吗,那么我很乐意接受。 很高兴听到它成功了!作为答案发布。 【参考方案1】:

让我详细讨论一下。我刚刚将它连接到远程服务器。你需要去你的jar文件所在的文件夹。假设,您要监控 X.jar 文件并假设它位于 usr/local/ 文件夹中。所以,首先 cd 进入文件夹。然后确定运行的是哪个jdk。你可以通过在linux中执行命令which java找到它。在远程服务器的命令行中(一般我们使用 PuTTy cmd)。在 puTTy cmd 中写入:

java -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.rmi.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.10.0 -jar X.jar

现在让我详细解释一下。这里需要定义rmi端口,因为jmx使用rmi。如果我们不定义 rmi 端口,它会自动分配一个随机端口。那么我们的连接就不会成功。我们不会使用身份验证和 ssl,因为这会造成困难。如果你愿意,你可以自己尝试。在主机名中,您必须指定远程主机名,即 IP 地址。 现在使用位于本地计算机中的 visualvm。一般可以在这个文件夹中找到:

C://Program Files/Java/jdk1.8.0_201/bin 

如果没有,则下载并将其粘贴到目录中。从本地电脑运行 visualvm。您将看到一些选项,例如本地、远程。在“远程”选项中选择“添加远程主机”。添加您的主机名。就我而言,它是 192.168.10.0。然后右键单击鼠标并选择“添加 jmx 连接”。将打开一个窗口并插入您的端口号。就我而言,它是 9010。您可以指定任何端口号。选择“不需要 ssl 连接”并且不要选择安全凭证。因为我们在属性中添加了身份验证为假。现在连接,您的连接将顺利进行。还有一个建议。您可以使用“jstatd 连接”进行连接。但它不起作用。不显示任何输出。可能是因为 java 8 问题左右。要监控内存详细信息,您需要更新版本的“visualvm.exe”。您可以下载它。 您可以使用身份验证和 SSL 进行连接。此链接中讨论了使用 Authentication=true 的详细步骤:Connect to remote JMX Agent with authentication

在此链接中讨论了同时使用 authentication=true 和 SSL = true 的详细步骤:JConsole SSL/TLS with Password Authentication

【讨论】:

【参考方案2】:

Arnab Biswas 的答案在我的情况下不起作用。经过一个小时的研究,我发现 JMX 运行在 RMI 之上,因此 JMX 使用了 2 个端口:

JMX 连接端口。 (-Dcom.sun.management.jmxremote.port) (臭名昭著的)漫游 RMI 数据端口。 (-Dcom.sun.management.jmxremote.rmi.port)

RMI 数据端口将打开一个从1099 开始的随机端口。通过将 RMI 注册中心和 RMI 服务器使用的端口设置为相同的端口,隧道会更容易。

所以我需要在 JVM 选项中添加-Dcom.sun.management.jmxremote.rmi.port=9010

我需要使用以下 JVM 选项:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.rmi.port=9010 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.59.99

了解更多:

http://hirt.se/blog/?p=289 https://realjenius.com/2012/11/21/java7-jmx-tunneling-freedom/ https://medium.com/codefountain/monitoring-using-java-visualvm-a25203d36390

【讨论】:

谢谢!!!!我正在慢慢发疯,试图与防火墙主机建立远程连接......恕我直言,这应该是公认的答案。似乎几乎没有人试图连接到防火墙后面的机器,所以他们都只是建议设置“com.sun.management.jmxremote.port”,但没有人提到“com.sun.management.jmxremote.rmi.port”.. . Ubuntu 在防火墙后面,UFW jmx,visualvm 这应该完成.. 添加此评论以便它可以在谷歌搜索中弹出:d【参考方案3】:

请使用以下 JVM 选项:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.59.99

在Jconsole中使用如下连接:

service:jmx:rmi:///jndi/rmi://192.168.59.99:9010/jmxrmi

【讨论】:

不经过身份验证就可以访问它似乎是个坏主意? @JackZachTibbles 在企业防火墙中很常见 顺便说一句,一旦用户有权访问正在运行的进程选项(例如 linux 上的 ps 命令),通过 -D 选项提供凭据就可以清楚地阅读,这通常是可能的通过 ssh 连接到您的服务器......所以......不确定它是否会给桌面带来很多安全性 好的,那么与作者提供的选项或连接有什么区别?请显示添加/删除的内容,否则很难为其他人进行此修复。 对不起。如果问题是针对我的,我将无法回答。那是4年前的事了。我继续前进,不再使用 Java 工作。 :-(

以上是关于使用 visualvm 和 JMX 进行远程监控的主要内容,如果未能解决你的问题,请参考以下文章

利用VisualVm和JMX远程监控Java进程

VisualVM通过JMX远程连接JVM

visualvm 可以通过 JMX 自动连接到远程进程吗?

使用 VisualVM 通过 Kubernetes 集群后面的 JMX 监控 dockerised Spring Boot 应用程序内部

[工具使用] visualvm 通过jmx不能连接

使用visualvm远程监控LINUX服务器JVM