如何将 VisualVM 附加到在 Docker 容器中运行的简单 Java 进程

2022-08-31 10:40:36

实际上,我想要一个适用于JEE容器的解决方案,特别是Glassfish,但是在我尝试了许多设置组合并且没有成功之后,我将设置简化为最简单的情况。

这是我在 Docker 容器中启动的 Hello World 守护程序。我想附加或附加到它。一切都在同一台机器上。jconsoleVisulaVM

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"]

建筑:docker build -t hello-world-daemon .

运行:docker run -it --rm --name hwd hello-world-daemon

问题:

  • 应该将哪些 JVM 参数添加到命令行?CMD
  • 应公开和发布哪些端口?
  • Docker 容器应该使用哪种网络模式?

我在这里不展示我失败的尝试,这样正确的答案就不会有偏见。这应该是一个非常普遍的问题,但我找不到一个有效的解决方案。

更新。工作解决方案

此 Dockerfile 工作正常

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

与 docker run 命令结合使用

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

VisualVM通过右键单击“本地->添加 JMX 连接”进行连接,然后输入 或通过添加远程主机进行连接。localhost:9010

JConsole通过使用 选择远程进程进行连接。localhost:9010

将连接定义为远程连接时,可以使用 列出的任何接口。例如,与地址的接口工作。容器的地址也有效。ifconfigdocker0172.17.0.1172.17.0.2


答案 1

首先,您应该使用以下 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

然后,您应该公开 docker 的端口:

EXPOSE 9010

还要使用 docker run 命令指定端口绑定:

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

之后,您可以使用 Jconsole 连接到本地 9010 端口,并管理在 Docker 中运行的应用程序。


答案 2

我关注了另一个SO对类似问题的回答,它有效。

我通过添加这些JVM参数在容器内启动了我的Java进程:

-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

并启动指定命令的 Docker 容器。-e HOST_HOSTNAME=$HOSTNAME -p <port>docker run

然后,我已经能够通过添加远程JMX连接(“文件”>“添加JMX连接...”)并在“连接”输入中指定并选中“不需要SSL连接”,从我的本地JVisualVm访问这个远程Java应用程序。<dockerhostname>:<port>


推荐