为何在配置JMX时Java打开3个端口?

Mic*_*ael 49 java jmx rmi

我在Centos6上使用JDK7运行我的Java程序.我使用以下选项启用JMX:

JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true"
Run Code Online (Sandbox Code Playgroud)

当我检查打开哪些端口时,我发现了2个额外的随机端口:

netstat -plunt | grep java
tcp        0      0 :::9123                     :::*                        LISTEN      13295/java
tcp        0      0 :::59927                    :::*                        LISTEN      13295/java
tcp        0      0 :::59928                    :::*                        LISTEN      13295/java
Run Code Online (Sandbox Code Playgroud)

请注意,每次重启仅配置的端口9123保持不变,另外两个端口会更改值.

netstat -plunt | grep java
tcp        0      0 :::9123                     :::*                        LISTEN      13331/java
tcp        0      0 :::59932                    :::*                        LISTEN      13331/java
tcp        0      0 :::59933                    :::*                        LISTEN      13331/java
Run Code Online (Sandbox Code Playgroud)

什么是2个额外端口以及为什么打开它们?

如何配置2个额外的随机端口?

如何配置::ffff:127.0.0.1将在JMX打开的所有端口之前显示?

为什么在与JConsole连接时不使用一个端口?

添加以澄清答案

不幸的是,附加的随机端口仍然打开为了提醒您,我使用Centos 6.我的Tomcat设置看起来像这样(Tomcat不部署任何应用程序):

CATALINA_OPTS="${CATALINA_OPTS}  -XX:+DisableAttachMechanism -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true -Djava.rmi.server.useLocalHostname=true -Djava.rmi.server.useCodebaseOnly=true -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.rmi.port=9123"
Run Code Online (Sandbox Code Playgroud)

Tomcat进程如下所示:

/usr/java/jdk1.7.0_51/bin/java -Djava.util.logging.config.file=/usr/tomcat-7.0.47/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -XX:+DisableAttachMechanism -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true -Djava.rmi.server.useLocalHostname=true -Djava.rmi.server.useCodebaseOnly=true -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.rmi.port=9123 -Djava.endorsed.dirs=/usr/tomcat-7.0.47/endorsed -classpath /usr/tomcat-7.0.47/bin/bootstrap.jar:/usr/tomcat-7.0.47/bin/tomcat-juli.jar -Dcatalina.base=/usr/tomcat-7.0.47 -Dcatalina.home=/usr/tomcat-7.0.47 -Djava.io.tmpdir=/usr/tomcat-7.0.47/temp org.apache.catalina.startup.Bootstrap start
Run Code Online (Sandbox Code Playgroud)

不幸的是,每次我看到额外的监听端口:

tcp        0      0 :::38830                    :::*                        LISTEN      790/java
tcp        0      0 ::ffff:127.0.0.1:8080       :::*                        LISTEN      790/java
tcp        0      0 :::9123                     :::*                        LISTEN      790/java
Run Code Online (Sandbox Code Playgroud)

附加运行:

tcp        0      0 ::ffff:127.0.0.1:8080       :::*                        LISTEN      2348/java
tcp        0      0 :::36252                    :::*                        LISTEN      2348/java
tcp        0      0 :::9123                     :::*                        LISTEN      2348/java
Run Code Online (Sandbox Code Playgroud)

顺便说一句,为什么我::ffff:127.0.0.1在RMI端口之前看不到?

第二次添加澄清评论

它与Tomcat无关.我试图用类似的设置运行ant:Ant进程看起来像这样:

/usr/bin/java -XX:+DisableAttachMechanism -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.local.only=true -Djava.rmi.server.useLocalHostname=true -Djava.rmi.server.useCodebaseOnly=true -Dcom.sun.management.jmxremote.port=9123 -Dcom.sun.management.jmxremote.rmi.port=9123 -classpath /usr/apache-ant-1.9.2/lib/ant-launcher.jar -Dant.home=/usr/apache-ant-1.9.2 -Dant.library.dir=/usr/apache-ant-1.9.2/lib org.apache.tools.ant.launch.Launcher -cp  sleep
Run Code Online (Sandbox Code Playgroud)

不幸的是,每次我看到额外的监听端口:

tcp        0      0 :::41200                    :::*                        LISTEN      13597/java
tcp        0      0 :::9123                     :::*                        LISTEN      13597/java
Run Code Online (Sandbox Code Playgroud)

附加运行:

tcp        0      0 :::58356                    :::*                        LISTEN      13629/java
tcp        0      0 :::9123                     :::*                        LISTEN      13629/java
Run Code Online (Sandbox Code Playgroud)

答:这是Java的错误

我成功地在Java上打开了bug:http: //bugs.java.com/bugdatabase/view_bug.do?bug_id=8035404

pet*_*erh 101

与普遍看法相反,JMX/RMI不需要打开所有这些端口.你实际上可以强迫它们相同,这意味着在一天结束时你只需要在防火墙上打一个洞(如果你担心防火墙).

尝试设置系统属性:

com.sun.management.jmxremote.port
com.sun.management.jmxremote.rmi.port
Run Code Online (Sandbox Code Playgroud)

达到同样的价值!!

明确设置这些将阻止RMI选择随机端口.将它们设置为相同的值将确保它打开更少的端口来监听.

这将在Java 7更新25或更高版本中有效.

什么是第三个港口?

您看到的第三个端口由您的应用程序打开(如果您遵循我的建议,则是第二个端口)由Java Attach API使用.这是JConsole用于连接"本地进程"的内容.默认情况下启用Java Attach API功能,因为Java 6与com.sun.management.jmxremote属性无关.此功能将使用随机端口,但它确实无关紧要,因为该功能仅允许来自主机本身的连接.如果您确实不喜欢此功能,则可以添加-XX:+DisableAttachMechanism到命令行以禁用Java Attach API功能.然后你将不再看到在随机端口上监听的java进程(在本例中为Tomcat).

如何仅在环回接口上进行JMX侦听

使用自定义应用程序,您将使用RMIServerSocketFactory,但这是Tomcat,因此您必须使用Tomcat的JMX远程生命周期监听器来完成它.

另一方面,com.sun.management.jmxremote.local.only从Java 7开始,您拥有该属性并不重要.它确保只允许来自主机本身的连接.请注意,JMX库没有通过绑定到loopback接口来实现这一点,这肯定是一种方法,但是由于主机可能有多个环回接口,因此也会略微不准确.

实际上大体上(最近添加了JDK和JMX)我会说Tomcat的JMX远程生命周期监听器现在是多余的,除非你想要绑定到一些非常奇怪的网络接口.

  • 我在Java上打开了bug:http://bugs.java.com/bugdatabase/view_bug.do?video_id = 8035404 (4认同)
  • @DanielSerodio。我阅读了 JDK 源代码。您可以在`sun.management.jmxremote.ConnectorBootstrap.java` 中找到它。 (2认同)
  • 谢谢@peterh.我尝试将两者都设置到同一个端口并得到`java.rmi.server.ExportException:端口已在使用:1099`.关于http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8035404的评论说两个端口需要分开. (2认同)
  • 我仍然可以看到第三个端口打开并在所有接口上侦听,这非常烦人。我检查了错误 URL,但没有发现任何有用的信息,因为上面写着“不是问题”。另外,`-XX:+DisableAttachMechanism`没有给我任何东西。在这里需要明确的是,我正在处理 Kafka,并且真的希望控制它的所有端口。有关如何禁用“Java Attach API”绑定到特定接口的任何建议。谷歌没有给我任何有用的东西。 (2认同)

use*_*436 7

使用 Oracle Java SE 1.8.0_121。

可以将 jmxremote.port 和 jmxremote.rmi.port 设置为相同的值,少打开一个端口。也可以设置 jmxremote.host=127.0.0.1,使该端口(或这两个端口,如果设置不同)仅绑定到环回接口。

另一个端口仍然是动态分配的,并将绑定到 0.0.0.0。我无法使用 -XX+DisableAttachMechanism 阻止此端口,也无法将其绑定到 0.0.0.0 以外的任何其他内容。