microservicios example application java docker jmx

example - java docker application



Cómo adjunto VisualVM a un proceso simple de Java que se ejecuta en un contenedor Docker (3)

En realidad, quería una solución que funcionara para contenedores JEE, específicamente para Glassfish, pero después de probar muchas combinaciones de configuraciones y no tuve éxito, reduje la configuración al caso más simple posible.

Aquí está mi daemon Hello World iniciado en un contenedor Docker. Quiero adjuntar jconsole o VisulaVM a él. Todo está en la misma máquina.

public class Main { public static void main(String[] args) { while (true) { try { Thread.sleep(3000); System.out.println("Hello, World"); } catch (InterruptedException e) { break; } } } }

Dockerfile

FROM java:8 COPY . /usr/src/myapp WORKDIR /usr/src/myapp RUN javac Main.java CMD ["java", "Main"]

Edificio: docker build -t hello-world-daemon .

Running: docker run -it --rm --name hwd hello-world-daemon

Preguntas:

  • ¿Qué parámetros de JVM deberían agregarse a la línea de comandos de CMD ?
  • ¿Qué puertos deberían estar expuestos y publicados?
  • ¿Qué modo de red debería usar el contenedor Docker?

No muestro mis intentos fallidos aquí para que las respuestas correctas no sean parciales. Este debería ser un problema bastante común, pero no pude encontrar una solución funcional.

Actualizar. Solución trabajada

Este Dockerfile funciona

FROM java:8 COPY . /usr/src/myapp WORKDIR /usr/src/myapp RUN javac Main.java CMD ["java", / "-Dcom.sun.management.jmxremote", / "-Dcom.sun.management.jmxremote.port=9010", / "-Dcom.sun.management.jmxremote.local.only=false", / "-Dcom.sun.management.jmxremote.authenticate=false", / "-Dcom.sun.management.jmxremote.ssl=false", "Main"] EXPOSE 9010

en combinación con el comando de ejecución del acoplador

docker run -it --rm --name hwd -p 9010:9010 hello-world-daemon

VisualVM conecta VisualVM clic con el botón secundario en Local-> Agregar conexión JMX , y luego ingresando localhost:9010 , o agregando un host remoto.

JConsole conecta seleccionando un proceso remoto con localhost:9010 .

Al definir la conexión como remota, se puede usar cualquier interfaz enumerada por ifconfig . Por ejemplo, la interfaz docker0 con la dirección 172.17.0.1 funciona. La dirección del contenedor 172.17.0.2 también funciona.


Al principio deberías ejecutar tu aplicación con estos parámetros de JVM:

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

Entonces debes exponer el puerto para el docker:

EXPOSE 9010

También especifique el enlace del puerto con el comando de ejecución del acoplador:

docker run -p 9010:9010 -it --rm --name hwd hello-world-daemon

Después de eso, puede conectarse con Jconsole al puerto local 9010 y administrar la aplicación que se ejecuta en Docker.


Como respondió Anthony . Tuve que usar la opción java -Djava.rmi.server.hostname en mi máquina con Windows.

Solo asegúrese de no usar el CMD en formato JSON en su archivo Docker, ya que no es compatible con la expansión del shell.

Ejemplo de Dockerfile:

FROM java:8 COPY . /usr/src/myapp WORKDIR /usr/src/myapp RUN javac Main.java #Do not use CMD in JSON format here because shell expansion doesn''t work in JSON format #Shell expansion is needed for the ${HOST} variable. CMD java -Dcom.sun.management.jmxremote=true / -Dcom.sun.management.jmxremote.rmi.port=9010 / -Dcom.sun.management.jmxremote.port=9010 / -Dcom.sun.management.jmxremote.ssl=false / -Dcom.sun.management.jmxremote.authenticate=false / -Dcom.sun.management.jmxremote.local.only=false / -Djava.rmi.server.hostname=${HOST} / Main


Seguí otra respuesta SO a una pregunta similar y funcionó.

Inicié mi proceso Java dentro del contenedor agregando esos parámetros JVM:

-Dcom.sun.management.jmxremote.port=<port> / -Dcom.sun.management.jmxremote.authenticate=false / -Dcom.sun.management.jmxremote.ssl=false / -Dcom.sun.management.jmxremote.rmi.port=<port> / -Djava.rmi.server.hostname=$HOST_HOSTNAME

e inició el contenedor Docker especificando -e HOST_HOSTNAME=$HOSTNAME -p <port> al comando de docker run del docker run .

Luego, he podido acceder a esta aplicación Java remota desde mi JVisualVm local al agregar una conexión JMX remota ("Archivo"> ​​"Agregar una conexión JMX ...") y especificar <dockerhostname>:<port> en el " Conexión "entrada y comprobación" No requiere conexión SSL ".