如何将VisualVM附加到在Docker容器中运行的简单Java进程
其实我想要一个适用于JEE容器的解决scheme,特别是Glassfish,但是当我尝试了许多设置的组合并且没有成功之后,我把设置简化为最简单的情况。
这是我在Docker容器中启动的Hello World守护进程。 我想附加jconsole
或VisulaVM
到它。 一切都在同一台机器上。
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"]
build设: docker build -t hello-world-daemon .
运行: docker run -it --rm --name hwd hello-world-daemon
问题:
- 什么JVM参数应该添加到
CMD
命令行? - 什么端口应该暴露和发布?
- Docker容器应该使用什么networking模式?
我不会在这里显示我的失败尝试,以便正确的答案不会有偏见。 这应该是一个相当普遍的问题,但我找不到一个工作的解决scheme。
更新。 工作的解决scheme
这个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
通过右键单击localhost:9010
>添加JMX连接 ,然后inputlocalhost:9010
,或通过添加远程主机。
JConsole
通过select远程进程与localhost:9010
。
将连接定义为远程时,可以使用ifconfig
列出的任何接口。 例如,地址172.17.0.1
docker0
接口起作用。 容器的地址172.17.0.2
适用。
起初,您应该使用这些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端口,并pipe理在Docker中运行的应用程序。
我跟着另外一个类似的问题的答复 ,它的工作。
我通过添加这些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>
到-e HOST_HOSTNAME=$HOSTNAME -p <port>
docker run
命令。
然后,通过添加远程JMX连接(“文件”>“添加JMX连接…”)并指定<dockerhostname>:<port>
,可以从本地JVisualVm访问此远程Java应用程序。连接“input,并检查”不需要SSL连接“。
正如安东尼回答的。 我必须在Windows机器上使用-Djava.rmi.server.hostname
java选项。
只要确保不要在Dockerfile中使用JSON格式的CMD,因为它不支持shell扩展。
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
- JMeter – docker – java.net.connectexception
- 如何连接到在Docker容器中运行的MongoDB?
- Docker磁盘空间问题留在主机上
- 用Docker运行PHPUnit
- 我的Docker WordPress网站在哪里存储数据?
- CPP Rest SDK http_listener在nano服务器中抛出exception(在Docker容器中)
- docker拉让我错误:“下载失败,重试:x509:由未知权威签名的证书”
- 更快的Google App Engine托pipe虚拟机部署(Python compat env)?
- 使用Confluent.Kafka从.net核心服务写入Kafka