settooltiptext - ¿Por qué Java abre 3 puertos cuando JMX está configurado?
jlabel definicion (4)
Al contrario de lo que comúnmente se cree, JMX / RMI no necesita abrir todos estos puertos. En realidad, puedes obligarlos a ser lo mismo, lo que significará que al final del día solo necesitarás perforar un agujero en el firewall (si el firewall es tu problema).
Prueba a configurar las propiedades del sistema:
com.sun.management.jmxremote.port
com.sun.management.jmxremote.rmi.port
al mismo valor !!
La configuración explícita de estos impedirá que RMI escoja puertos aleatorios. Al establecerlos en el mismo valor, se asegurará de que abre menos puertos para escuchar.
Esto funcionará en la actualización 25 de Java 7 o posterior.
¿Cuál es el tercer puerto?
El tercer puerto que ve abierto por su aplicación (o el segundo si siguió mi consejo anterior) es utilizado por la API de Java Attach . Es lo que JConsole usa para conectarse al "Proceso local". La característica Java Attach API está habilitada por defecto desde Java 6 independientemente de la propiedad com.sun.management.jmxremote
. Esta función utilizará un puerto aleatorio, pero realmente no importa porque la función solo permite conexiones desde el propio host. Si realmente no le gusta esta función, puede agregar -XX:+DisableAttachMechanism
a la línea de comando para deshabilitar la característica API Java Attach. Entonces ya no verá el proceso java (en este caso Tomcat) escuchando en un puerto aleatorio.
¿Cómo puedo hacer que JMX escuche únicamente en la interfaz loopback?
Con una aplicación personalizada, usaría un RMIServerSocketFactory pero este es Tomcat, por lo que tendría que hacerlo utilizando el JMX Remote Lifecycle Listener de Tomcat.
Por otro lado, ahora no importa que tenga la propiedad com.sun.management.jmxremote.local.only
desde Java 7. Se asegura de que solo se permitan las conexiones desde el host. Tenga en cuenta que la biblioteca JMX no logra esto mediante el enlace a la interfaz de bucle de retorno, que sin duda sería una forma de hacerlo, pero también un poco impreciso, ya que un host puede tener varias interfaces de bucle invertido.
De hecho, en general (con las últimas incorporaciones a JDK wrt JMX), diría que el JMX Remote Lifecycle Listener de Tomcat ahora es redundante, excepto si desea vincularse a una interfaz de red realmente extraña.
Ejecuto mi programa Java con JDK7 en Centos6. Habilizo JMX usando las siguientes opciones:
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"
Cuando compruebo qué puertos están abiertos, descubro 2 puertos aleatorios adicionales:
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
Tenga en cuenta que cada reinicio solo con el puerto 9123 permanece igual y que dos puertos adicionales cambian de valor.
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
¿Qué son 2 puertos adicionales y por qué están abiertos?
¿Cómo puedo configurar 2 puertos aleatorios adicionales?
¿Cómo puedo configurar ::ffff:127.0.0.1
aparecerá antes de todos los puertos abiertos por JMX?
¿Por qué no se usa un puerto cuando se conecta con JConsole?
Agregado para aclarar la respuesta
Desafortunadamente, el puerto aleatorio adicional aún está abierto. Para recordarle, utilizo Centos 6. La configuración de mi Tomcat se ve así (Tomcat no implementa ninguna aplicación):
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"
El proceso de Tomcat se ve así:
/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
Lamentablemente, cada vez que veo un puerto de escucha adicional:
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
Ejecución adicional:
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
Por cierto, ¿por qué no puedo ver ::ffff:127.0.0.1
antes de los puertos RMI?
Se agregó por segunda vez para aclarar el comentario
No está relacionado con Tomcat. He intentado ejecutar hormiga con configuraciones similares: el proceso Ant se ve así:
/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
Lamentablemente, cada vez que veo un puerto de escucha adicional:
tcp 0 0 :::41200 :::* LISTEN 13597/java
tcp 0 0 :::9123 :::* LISTEN 13597/java
Ejecución adicional:
tcp 0 0 :::58356 :::* LISTEN 13629/java
tcp 0 0 :::9123 :::* LISTEN 13629/java
Respuesta: Es un error de Java
Tengo éxito en abrir un error en Java: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8035404
Porque jmx está encapsulado en rmi, que es muy cortafuegos y antipático. Evítalo si puedes, hay una encapsulación alternativa llamada jmxmp.
Échele un vistazo, eso podría ayudarlo: http://blog.markfeeney.com/2010/10/jmx-through-ssh-tunnel.html http://jrds.fr/sourcetype/jmx/start#jmx_protocols
Según el tema que Michael abrió, este parece ser un comportamiento esperado https://bugs.openjdk.java.net/browse/JDK-8035404
Usando Oracle Java SE 1.8.0_121.
Es posible establecer jmxremote.port y jmxremote.rmi.port en el mismo valor, se abre un puerto menos. También es posible configurar jmxremote.host = 127.0.0.1, para tener ese puerto (o esos dos puertos, si los configura de forma diferente) se enlaza únicamente a la interfaz de bucle invertido.
Sin embargo, otro puerto aún se asigna dinámicamente y se vinculará a 0.0.0.0. No pude evitar este puerto con -XX + DisableAttachMechanism, y tampoco pude vincularlo a otra cosa que no sea 0.0.0.0.