使用jConsole连接远程Tomcat JMX实例

56

我正在尝试使用jConsole连接到远程的Tomcat JMX实例,但是无法成功连接。有任何想法吗?

我在远程的Tomcat catalina.sh 中加入了以下选项:

JAVA_OPTS="$JAVA_OPTS -Dcom.sun.management.jmxremote \
    -Dcom.sun.management.jmxremote.port=9004 \
    -Dcom.sun.management.jmxremote.ssl=false \
    -Dcom.sun.management.jmxremote.authenticate=false"

你正在运行Tomcat的打包版本还是手动安装的版本?另外,请你把完整的错误信息粘贴过来好吗? - Pascal Thivent
相似问题:https://dev59.com/hHVC5IYBdhLWcg3w51hv - Vadzim
12个回答

63

我遇到了类似的问题。如果我在本地机器上启动jconsole,我可以连接到JMX服务器。

看起来RMI服务器没有侦听正确的IP地址。所以,正如这个相关问题中建议的那样,我添加了以下内容:

-Djava.rmi.server.hostname=<host ip>

JAVA_OPTS也加入其中,然后它就起作用了。


1
对我来说有效,我只是将主机IP设置为127.0.0.1,在我的本地机器上它对我有效。 - rado
我们将其添加到服务器的JAVA_OPTS还是本地机器的JAVA_OPTS? - Joshua Partogi
太棒了,我在使用JMX监控远程ActiveMQ时遇到了同样的问题。这个解决了它。非常感谢。 - Khue Vu
不适用于我。我有LAS-tomcat。我认为设置可能不同。 - vsingh

37

我从StackOverflow上收集了信息,并根据其他成员的提示找到了这些信息。

JMX带来的大部分痛苦(在我看来)是JMX打开了第二个动态分配的网络端口。如防火墙(例如iptables)会阻止此端口。

适用于Linux上的Tomcat的解决方案:

使用Tomcat 6.0.24或更新版本 从Apache Tomcat Extras下载catalina-jmx-remote.jar(在Tomcat下载页面上使用浏览器) 将其复制到$CTALINA_HOME\lib中

这样可以设置JMX使用的两个端口

编辑server.xml中的Server部分

<Server port="8005" ..>
  ...
  <Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="9840" rmiServerPortPlatform="9841"/>

设置一些环境变量(例如在setenv.sh中)

CATALINA_OPTS="
  -Djava.rmi.server.hostname=IP-TO-LISTEN
  -Dcom.sun.management.jmxremote.password.file=$CATALINA_BASE/conf/jmxremote.password 
  -Dcom.sun.management.jmxremote.access.file=$CATALINA_BASE/conf/jmxremote.access 
  -Dcom.sun.management.jmxremote.ssl=false"

这将激活JMX的访问控制。

jmxremote.access会如下所示

monitorRole readonly
controlRole readwrite

将结束 jmxremote.password

monitorRole tomcat
controlRole tomcat

(只是简单的空格)

重新启动Tomcat。

现在在服务器上配置防火墙(例如iptables)。

/etc/sysconfig/iptables

-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 9840 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 9841 -j ACCEPT

还有 /etc/sysconfig/ip6tables

-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 9840 -j ACCEPT
-A RH-Firewall-1-INPUT -m tcp -p tcp --dport 9841 -j ACCEPT

重启iptables。

完成!

现在使用VisualVM或JConsole连接到rmiRegistryPortPlatform,我们的示例中为9840。

如果工作站和服务器之间没有更多的防火墙,则应该可以正常工作。


3
谢谢您的肯定!非常成功!我只需要再加上一行:-Djava.rmi.server.hostname=<server-name> - Ortwin Angermeier
在tomcat.conf中也应该是-Dcom.sun.management.jmxremote.port=9840吗? - Nic Cottrell
我明白了 - 监听器会处理端口。但是在这个例子中,你使用什么连接字符串? - Nic Cottrell
@NicholasTolleyCottrell:连接字符串类似于monitorRole@IP-TO-LISTEN:9840或service:jmx.rmi:///jndi/rmi/IP-TO-LISTEN:9840。 - Hajo Thelen
@NicholasTolleyCottrell:我们不需要使用参数设置端口。它是通过server.xml中的监听器配置完成的。 - Hajo Thelen

13

尝试使用Java 8

1. 将以下内容添加到你的Java Tomcat启动脚本中:

-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

比如将以下内容添加到bin/setenv.sh中:

export CATALINA_OPTS="$CATALINA_OPTS \
-Dcom.sun.management.jmxremote.port=1616 \
-Dcom.sun.management.jmxremote.rmi.port=1616 \
-Dcom.sun.management.jmxremote.local.only=true \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false "

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.: 在第二步中,使用ssh-L选项指定本地(客户端)主机上的端口1616将被转发到远程主机。
  • P.S.2:您可以为JMX和RMI会话指定相同的端口。

感谢,我能够在同一个端口中运行rmiregistry和rmicomm。这可以在没有tomcat/conf/server.xml JMXRemoteLifecycleListener的情况下工作。如果不使用该侦听器,有什么问题应该注意吗? - Whome
@Whome 抱歉,我错过了你的评论。在我的经验中,没有任何反对意见。 - freedev

8

您使用什么字符串作为JMX连接URL?我并不是想指出显而易见的问题,但是JConsole界面很糟糕,对我来说需要一个过于复杂的URL才能连接到远程JMX应用程序。我的URL看起来像这样:

service:jmx:rmi:///jndi/rmi://(hostname):(jmxport)/jmxrmi

3

在Tomcat8中启用JMX,在我的POC中已成功测试

1/ 从Apache网站下载catalina-jmx-remote.jar并放置在$CATALINA_HOME/lib中。

2/ 备份server.xml/setenv.sh。对server.xml进行以下更改-

<Listener className="org.apache.catalina.mbeans.JmxRemoteLifecycleListener" rmiRegistryPortPlatform="10001" rmiServerPortPlatform="10002" />

3/ 将更改应用于$CATALINA_BASE/bin/setenv.sh文件,如下所示 -

[...]

JVM_OPTS="[...] 
-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.authenticate=true 
-Djava.rmi.server.hostname=<eth:0_IP>| <`hostname -i`> 
-Dcom.sun.management.jmxremote.password.file=/apps/data/apache-tomcat-8_8080/conf/jmxremote.password 
-Dcom.sun.management.jmxremote.access.file=/apps/data/apache-tomcat-8_8080/conf/jmxremote.access 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.local.only=false 
-Dcom.sun.management.jmxremote=true "

4/ 创建两个文件 - $touch $CATALINA_BASE/conf/jmxremote.password 包含:

admin letmein

$touch $CATALINA_BASE/conf/jmxremote.access 包含:

admin readwrite

$ chmod 600 jmxremote.password

5/ 重新启动Tomcat,并使用JConsole测试 :)

$echo|telnet 10.105.14.90 10001

2
当你说“但无法成功连接”时,你指的是什么?是否有错误信息?尝试在jconsole中打开日志记录,看看是否有帮助进行调试。
要打开jconsole日志记录,请编辑一个名为logging.properties的文件,并将其添加到您将在其中运行jconsole的目录中:
handlers= java.util.logging.ConsoleHandler

.level=INFO

java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter

java.util.logging.ConsoleHandler.level = FINEST
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

javax.management.level=FINEST
javax.management.remote.level=FINEST

接下来,使用以下命令启动jconsole:

jconsole -J-Djava.util.logging.config.file=logging.properties

Joe,我遇到了以下异常。忽略日志记录错误,请建议问题出在哪里。在com.sun.jmx.remote.util.ClassLogger.finer(ClassLogger.java:130)处 在com.sun.jmx.remote.util.ClassLogger.trace(ClassLogger.java:88)处 在javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:245)处 在javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:227)处 在sun.tools.jconsole.ProxyClient.tryConnect(ProxyClient.java:334)处 在sun.tools.jconsole.ProxyClient.connect(ProxyClient.java:296)处 在sun.tools.jconsole.VMPanel$2.run(VMPanel.java:280)处 - Niger
抱歉,我的logging.properties文本中有一个打字错误。我已经编辑了我的帖子,请尝试重新创建该文件并查看是否可以获得一些调试信息。 - joe p
不,我们无法查看日志。这些日志是在哪里创建的? - Java Guy

2
如果您正在使用Linux操作系统,需要修改catalina.sh文件并添加以下内容:
                CATALINA_OPTS="-Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=<HOST_IP> -Dcom.sun.management.jmxremote.port=<HOST_PORT> -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
            export CATALINA_OPTS

或者以root身份修改/etc/profile文件并重新运行该文件(source /etc/profile)

如果您正在Windows上工作,并且从命令行启动Tomcat,请使用环境变量CATALINA_OPTS

如果您正在Windows上工作,并且将Tomcat作为服务启动,则需要使用监视器服务实用程序来配置服务初始化参数(setenv.bat,catalina.bat或env-vars均无效)。为此,您需要在services.msc中列出的服务名称(例如jasperreportsTomcat)。之后,您需要以管理员身份打开控制台并执行以下操作(例如):   tomcat6w.exe //MS//jasperreportsTomcat

使用此命令将显示一个托盘图标,您可以打开一个面板。现在,在“Java”选项卡中,您可以修改jmx选项。请注意不要添加尾随空格,并使用“[enter]”符号逐行分隔每个选项行。

-Dcom.sun.management.jmxremote
-Djava.rmi.server.hostname=192.168.61.101
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

希望能对您有所帮助


1

检查您的服务器是否在防火墙后面。JMX基于RMI,启动时会打开两个端口。一个是注册端口,默认为1099,可以通过com.sun.management.jmxremote.port选项指定。另一个是用于数据通信的随机端口,这就是问题所在。好消息是,从JDK6开始,可以通过com.sun.management.jmxremote.rmi.port选项指定此随机端口。

在您的{tomcat_dir}/bin/setenv.sh中添加以下行:

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"

1
我有一些东西要给你们所有人,为了完成整个事情的调查。有一个技巧,就是分析器工具使用一个端口连接jvm,但jvm继续使用另一个随机端口进行对话。如果jvm在远程机器内运行(例如:tomcat web应用程序服务器),并且远程机器有防止出站和入站连接的保护,您必须将java系统属性com.sun.management.jmxremote.rmi.port设置为与名为com.sun.management.jmxremote.port的属性相同的值。
来源: https://serverfault.com/questions/308662/how-do-i-fix-a-failed-to-retrieve-rmiserver-stub-jmx-error 还要看看这个: http://blog.cantremember.com/debugging-with-jconsole-jmx-ssh-tunnels/ 希望能为大家做出贡献!
祝好运!

0

专业提示:您需要修复(即确定数量)RMI注册表和JMX / RMI服务器端口。您可以通过将jar文件放入lib-dir并配置特殊侦听器来完成此操作。(当然还有激活JMX的常规标志)

    -Dcom.sun.management.jmxremote  \
    -Dcom.sun.management.jmxremote.port=8999 \
    -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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接