当前位置: 首页 > 知识库问答 >
问题:

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

彭炳
2023-03-14

实际上,我想要一个适用于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 容器应该使用什么网络模式?

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

更新。有效的解决方案

这个docker文件有效

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

< code>VisualVM通过右击本地连接-

JConsole 通过选择与本地主机:9010 的远程进程进行连接。

将连接定义为远程时,可以使用< code>ifconfig列出的任何接口。例如,地址为< code>172.17.0.1的< code>docker0接口可以工作。容器的地址< code>172.17.0.2也有效。

共有3个答案

孔砚
2023-03-14

FWIW,这是我如何将VisualVM连接到运行在macOS上的Docker容器中的Java进程的:

主.java:

public class Main {
    public static void main(String args[]) throws Exception {
        while (true) {
            System.out.print("Hello ");
            System.out.println("world");
            Thread.sleep(1000);
        }
    }
}

Dockerfile文件:

FROM openjdk:11.0.2-slim
COPY Main.class /
WORKDIR /
ENTRYPOINT ["java", \
"-Dcom.sun.management.jmxremote=true", \
"-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", \
"-Dcom.sun.management.jmxremote.rmi.port=9010", \
"-Djava.rmi.server.hostname=localhost", \
"Main"]

编译 Java 代码,构建映像并运行容器,如下所示:

$ javac Main.java
$ docker build -t main .
$ docker run -p 9010:9010 -it main

然后使用JMX将VisualVM连接到本地主机:9010

商正浩
2023-03-14

我跟踪了另一个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

然后,我可以通过添加远程JMX连接(“文件”)从本地JVisualVm访问此远程Java应用程序

束新
2023-03-14

首先,您应该使用以下 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中运行的应用程序。

 类似资料:
  • 问题内容: 实际上,我想要一个适用于JEE容器(特别是Glassfish)的解决方案,但是在尝试了多种设置组合但没有成功后,我将设置简化为最简单的情况。 这是我在Docker容器中启动的Hello World守护程序。我想附加或附加到它。一切都在同一台机器上。 Docker文件 建造: 运行: 问题: 哪些JVM参数应添加到命令行? 应该公开和发布哪些端口? Docker容器应使用哪种网络模式?

  • 我使用命令在我的macOS Big Sur上运行带有Ubuntu Xenial映像的docker容器,它工作正常,给我一个Linux的终端。 然而,我想将一个卷附加到我的容器中,这样我就可以将我在ubuntu终端中所做的工作保存在Mac文件系统的容器中。为此,我尝试运行以下命令: sudo docker run-it ubuntu:xenial-v/Users/myname/Documents/U

  • 在部署时,我面临一个“CrashLoopBackoff”错误。Net核心API和

  • 问题内容: 我需要在Windows Docker容器内附加到PATH,并且尝试了许多排列。 这些都不起作用:它们不评估预先存在的PATH变量。 追加到PATH的正确语法是什么?我什至可以在Docker内部添加到PATH吗?(我可以在类似的Linux容器上使用) 问题答案: 不幸的是,这是行不通的,因为Windows环境变量的工作方式与linux有所不同。更多信息 到目前为止,唯一的方法是通过 但是

  • 我需要在AWS EC2服务器(Ubuntu18.04 LTS)上的docker run命令启动的运行容器上附加一个卷,并使用以下命令 我使用的是Docker版本19.03.12。

  • 我有一个Sinatra应用程序,在Docker中运行良好: 但是当我尝试添加Redis时: Redis似乎没有启动。 那么,将Redis添加到Ruby()Docker容器中的好方法是什么呢?