为什么Java在configurationJMX时打开3个端口?

我在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" 

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

 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 

请注意,每个重新启动只configuration端口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 

什么是2个额外的端口,为什么他们打开?

我怎样才能configuration2个附加的随机端口?

我如何configuration::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" 

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 

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

 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 

额外运行:

 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 

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

第二次添加澄清评论

这与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 

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

 tcp 0 0 :::41200 :::* LISTEN 13597/java tcp 0 0 :::9123 :::* LISTEN 13597/java 

额外运行:

 tcp 0 0 :::58356 :::* LISTEN 13629/java tcp 0 0 :::9123 :::* LISTEN 13629/java 

答:这是Java的错误

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

与常见的观点相反,JMX / RMI不需要打开所有这些端口。 你可以强迫它们相同,这意味着在一天结束的时候,你只需要在防火墙上打一个洞(如果防火墙是你关心的话)。

尝试设置系统属性:

 com.sun.management.jmxremote.port com.sun.management.jmxremote.rmi.port 

到相同的价值!

显式设置这些将阻止RMI挑选随机端口。 将它们设置为相同的值将确保它打开较less的端口来侦听。

这将在Java 7更新25或更高版本中工作。

什么是第三个港口?

Java Attach API会使用您看到的第三个由您的应用程序打开的端口(或者,如果您遵循上述build议,则是第二个端口)。 JConsole用于连接到“本地进程”。 无论com.sun.management.jmxremote属性如何,自Java 6以来,Java Attach APIfunction都是默认启用的。 此function将使用随机端口,但它并不重要,因为该function只允许来自主机本身的连接。 如果您真的不喜欢这个function,那么您可以在命令行中添加-XX:+DisableAttachMechanism以禁用Java Attach APIfunction。 然后你将不再看到在一个随机端口上监听的java进程(在这个例子中是Tomcat)。

如何让JMX只在回送接口上侦听

使用定制的应用程序,您可以使用RMIServerSocketFactory,但这是Tomcat,因此您必须使用Tomcat的JMX Remote Lifecycle Listener来执行此操作。

另一方面,自从Java 7以来,您拥有com.sun.management.jmxremote.local.only属性并不重要。它确保只允许来自主机的连接。 请注意,JMX库并没有通过绑定到loopback接口来实现这一点,这肯定会这样做的一种方式,但也有些不准确,因为主机可能有几个回送接口。

实际上总的来说(最近增加了JDK和JMX)我会说Tomcat的JMX远程生命周期监听器现在是多余的,除非你想绑定一些非常奇怪的networking接口。

因为jmx封装在rmi中,所以非常防火墙和nat不友好。 如果可以的话,避免它,还有一个名为jmxmp的替代封装。

看看,这可能会帮助你: http : //blog.markfeeney.com/2010/10/jmx-through-ssh-tunnel.html http://jrds.fr/sourcetype/jmx/start#jmx_protocols

按照迈克尔打开这个问题似乎是一个预期的行为https://bugs.openjdk.java.net/browse/JDK-8035404