web-dev-qa-db-fra.com

Pourquoi Java ouvre 3 ports lorsque JMX est configuré?

J'exécute mon programme Java avec JDK7 sur Centos6. J'active JMX en utilisant les options suivantes:

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"

Lorsque je vérifie quels ports sont ouverts, je découvre 2 ports aléatoires supplémentaires:

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

Veuillez noter que chaque redémarrage seul le port configuré 9123 reste le même, et deux ports supplémentaires modifient les valeurs.

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

Que sont 2 ports supplémentaires et pourquoi sont-ils ouverts?

Comment configurer 2 ports aléatoires supplémentaires?

Comment puis-je configurer ::ffff:127.0.0.1 apparaîtra avant tous les ports ouverts par JMX?

Pourquoi un port n'est pas utilisé lors de la connexion avec JConsole?

Ajouté pour clarifier la réponse

Malheureusement, le port aléatoire supplémentaire est toujours ouvert. Pour rappel, j'utilise Centos 6. Mes paramètres Tomcat ressemblent à ceci (Tomcat ne déploie aucune application):

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"

Le processus Tomcat ressemble à ceci:

/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

Malheureusement, chaque fois que je vois un port d'écoute supplémentaire:

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

Exécution supplémentaire:

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, pourquoi je ne vois pas ::ffff:127.0.0.1 avant les ports RMI?

Ajouté une deuxième fois pour clarifier le commentaire

Il n'est pas lié à Tomcat. J'ai essayé d'exécuter ant avec des paramètres similaires: le processus Ant ressemble à ceci:

/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

Malheureusement, chaque fois que je vois un port d'écoute supplémentaire:

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

Exécution supplémentaire:

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

Réponse: c'est le bug de Java

J'ai réussi à ouvrir un bug sur Java: http://bugs.Java.com/bugdatabase/view_bug.do?bug_id=8035404

47
Michael

Contrairement à la croyance commune, JMX/RMI n'a pas besoin d'ouvrir tous ces ports. Vous pouvez en fait les forcer à être les mêmes, ce qui signifie qu'à la fin de la journée, vous n'aurez qu'à percer un trou dans le pare-feu (si le pare-feu vous concerne).

Essayez de définir les propriétés du système:

com.Sun.management.jmxremote.port
com.Sun.management.jmxremote.rmi.port

à la même valeur !!

Leur définition explicite empêchera RMI de choisir des ports aléatoires. En les réglant sur la même valeur, vous vous assurerez qu'il ouvre moins de ports à écouter.

Cela fonctionnera dans Java 7 mise à jour 25 ou ultérieure.

Quel est le troisième port?

Le troisième port que vous voyez ouvert par votre application (ou le second si vous avez suivi mes conseils ci-dessus) est utilisé par l'API Java Attach . C'est ce que JConsole utilise pour se connecter au "processus local". La fonction Java Attach API est activée par défaut depuis Java 6 quel que soit le com.Sun.management.jmxremote propriété. Cette fonctionnalité utilisera un port aléatoire mais cela n'a pas vraiment d'importance car la fonctionnalité autorise uniquement les connexions depuis l'hôte lui-même. Si vous n'aimez pas vraiment cette fonctionnalité, vous pouvez ajouter -XX:+DisableAttachMechanism à la ligne de commande pour désactiver la fonction Java Attach API). Ensuite, vous ne verrez plus le processus Java (dans ce cas Tomcat) écouter sur un port aléatoire.

Comment faire pour que JMX écoute sur l'interface de bouclage uniquement

Avec une application sur mesure, vous utiliseriez un RMIServerSocketFactory mais c'est Tomcat, vous devez donc le faire en utilisant JMX Remote Lifecycle Listener .

D'un autre côté, peu importe maintenant que vous avez le com.Sun.management.jmxremote.local.only propriété depuis Java 7. Il s'assure que seules les connexions de l'hôte lui-même sont autorisées. N'oubliez pas que la bibliothèque JMX n'y parvient pas en se liant à l'interface de bouclage qui serait certainement une façon de le faire mais aussi légèrement inexacte car un hôte peut potentiellement avoir plusieurs interfaces de bouclage.

En fait, dans l'ensemble (avec les ajouts les plus récents à JDK par rapport à JMX), je dirais que l'écouteur de cycle de vie à distance de Tomcat JMX est désormais redondant sauf si vous le souhaitez pour se lier à une interface réseau vraiment étrange.

97
peterh

Utilisation d'Oracle Java SE 1.8.0_121.

Il est possible de définir jmxremote.port et jmxremote.rmi.port sur la même valeur, c'est un port de moins ouvert. Il est également possible de définir jmxremote.Host = 127.0.0.1, pour que ce port (ou ces deux ports, si vous les définissez différemment) soit lié à l'interface de bouclage uniquement.

Un autre port est toujours assigné dynamiquement et sera lié à 0.0.0.0. Je n'ai pas été en mesure d'empêcher ce port avec -XX + DisableAttachMechanism, et j'ai également été incapable de le lier à autre chose que 0.0.0.0.

4
user2679436

Parce que jmx est encapsulé dans rmi, ce qui est très pare-feu et peu convivial. Évitez-le si vous le pouvez, il existe une encapsulation alternative appelée jmxmp.

Jetez un œil, cela pourrait vous aider: http://blog.markfeeney.com/2010/10/jmx-through-ssh-tunnel.htmlhttp: // jrds. fr/sourcetype/jmx/start # jmx_protocols

3
fbacchella