为什么 Java 在配置 JMX 时会打开 3 个端口?

2022-08-31 14:19:12

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

当我检查打开了哪些端口时,我发现另外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

请注意,每次重新启动时,仅配置的端口 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 个附加端口,为什么打开它们?

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

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

为什么在与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

第二次添加以澄清注释

它与雄猫无关。我试图用类似的设置运行蚂蚁:蚂蚁过程看起来像这样:

/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上打开了错误:http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8035404


答案 1

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

尝试设置系统属性:

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

到相同的价值!!

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

这将适用于 Java 7 更新 25 或更高版本。

什么是第三个端口?

您看到的应用程序打开的第三个端口(或者如果您遵循我上面的建议,则使用第二个端口)由Java Attach API使用。这是JConsole用于连接到“本地进程”的内容。自 Java 6 起,Java Attach API 功能缺省情况下处于启用状态,而不管属性如何。此功能将使用随机端口(也称为操作系统临时端口),但实际上并不重要,因为该功能仅允许来自主机本身的连接。如果您真的不喜欢此功能,则可以添加到命令行以禁用 Java Attach API 功能。然后,您将不再看到java进程(在本例中为Tomcat)在随机端口上侦听。com.sun.management.jmxremote-XX:+DisableAttachMechanism

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

使用定制的应用程序,您将使用RMIServerSocketFactory,但这是Tomcat,因此您必须使用Tomcat的JMX远程生命周期侦听器来执行此操作。

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

事实上,总的来说(随着JDK wrt JMX的最新添加),我会说Tomcat的JMX远程生命周期监听器现在是多余的,除非你想绑定到一些非常奇怪的网络接口。


答案 2

使用 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以外的任何内容。


推荐