Why Java opens 3 ports when JMX is configured?

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

I run my Java program with JDK7 on Centos6. I enable JMX using the following options:

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" 

When I check what ports are opened I discover 2 additional random ports:

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 

Please note that each restart only configured port 9123 remains same, and two additional ports change values.

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 

What are 2 additional ports and why they are opened?

How can I configure 2 additional random ports?

How can I configure ::ffff:127.0.0.1 will appear before all ports opened by JMX?

Why one port is not used when connecting with JConsole?

Added to clarify the answer

Unfortunately, the additional random port is still opened To remind you, I use Centos 6. My Tomcat settings are look like this (Tomcat does not deploy any applications):

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 process looks like this:

/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 

Unfortunately, each time I see additional listening port:

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 

Additional run:

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 

BTW, why I can not see ::ffff:127.0.0.1 before RMI ports?

Added second time to clarify the comment

It is not related to Tomcat. I have tried to run ant with similar settings: Ant process looks like this:

/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 

Unfortunately, each time I see additional listening port:

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

Additional run:

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

Answer: It is Java's bug

I success to open bug on Java: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8035404

回答1:

Contrary to common belief JMX/RMI doesn't need to open all these ports. You can actually force them to be same which will mean that at the end of the day you'll only need to punch one hole in the firewall (if firewall is your concern).

Try setting System Properties:

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

to the same value!!

Explicitly setting these will stop RMI from picking random ports. Setting them to the same value will make sure it opens less ports to listen on.

This will work in Java 7 update 25 or later.

What is the third port?

The third port that you see opened by your application (or the second if you followed my advice above) is used by the Java Attach API. It is what JConsole uses for connecting to "Local Process". The Java Attach API feature is enabled by default since Java 6 regardless of the com.sun.management.jmxremote property. This feature will use a random port but it really doesn't matter because the feature only allows connections from the host itself. If you really dislike this feature then you can add -XX:+DisableAttachMechanism to the command line to disable the Java Attach API feature. Then you'll no longer see the java process (in this case Tomcat) listening on a random port.

How do I make JMX listen on the loopback interface only

With a custom made application you would use a RMIServerSocketFactory but this is Tomcat so you would have to do it using Tomcat's JMX Remote Lifecycle Listener.

On the other hand it doesn't matter now that you have the com.sun.management.jmxremote.local.only property since Java 7. It makes sure that only connections from the host itself are allowed. Mind you that JMX library doesn't achieve this by binding to loopback interface which would certainly be one way of doing it but also slight inaccurate as a host can potentially have several loopback interfaces.

In fact by and large (with the most recent additions to JDK wrt JMX) I would say that Tomcat's JMX Remote Lifecycle Listener is now redundant except if you want to bind to some really odd network interface.



回答2:

Because jmx is encapsulated in rmi wich is very firewall and nat unfriendly. Avoid it if you can, there is an alternative encapsulation called jmxmp.

Have a look at, that might help you : http://blog.markfeeney.com/2010/10/jmx-through-ssh-tunnel.html http://jrds.fr/sourcetype/jmx/start#jmx_protocols



回答3:

As per issue that Michael opened this seems to be an expected behavior https://bugs.openjdk.java.net/browse/JDK-8035404



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!