如何在Docker中监控Java应用程序的内存使用情况

11

我在Docker容器中的Tomcat上运行Java Web应用程序。

有没有办法监视Java应用程序的内存使用情况? 我尝试使用jconsole和Docker的进程ID,但它告诉我Invalid process id

我还启用了Tomcat中的JMX,但不知道如何绑定它。 我可以使用本地的visualvm绑定主机,但找不到绑定到主机内部的Docker的方法。

有没有好的方法实现这一点?

谢谢


1
要获取整体内存使用情况,您应该能够监视Docker容器进程,对吧?不能使用jconsole,因为那不是Java进程,而是使用Linux工具,如toppssmem等。或者您正在谈论内存调试并且需要更详细的信息? - qkrijger
@qkrijger 是的,我想调试内存泄漏问题。我知道我可以在本地运行应用程序来做这件事。只是想知道是否有远程方法来实现这一点。谢谢。 - Browny Lin
1
好的,你可以在你的主机上运行jconsole,并使用https://dev59.com/AHRA5IYBdhLWcg3wtwSe,在Docker中暴露JMX远程端口,这样做是可行的。 - qkrijger
6个回答

12

要连接到在运行boot2docker中的Docker容器中运行的Java进程,您可以尝试以下操作:

使用以下选项启动您的Java进程:

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=<boot2docker_ip> \
<Main>

你需要使用--expose <port> -p <port>:<port>来运行你的镜像。

然后在visualvm中添加JMX连接,连接地址为<boot2docker_ip>:<port>

如果没有boot2docker,这个过程应该不会有太大区别。


2
请确保您没有使用选项“-Dcom.sun.management.jmxremote.local.only=false”,因为这是导致它无法正常工作的原因。您的答案帮助我找到了解决方法。谢谢! - Joao Baltazar

3

要监视它的使用情况,您需要获取它的真实进程ID。如果您直接在容器中运行tomcat,则应该是:

DOCKER_ROOT_PROC=`(docker inspect -f "{{ .State.Pid }}" my_container)`

如果您使用的是像Phusion的baseimage之类的东西,那么您的Java进程将成为该进程的子进程。要查看层次结构,请使用以下命令:

pstree $DOCKER_ROOT_PROC

一旦你掌握了这一点,你就可以使用它来编写你的脚本。
ps -o pid,cmd --no-headers --ppid $DOCKER_ROOT_PROC

在您的脚本中,通过递归查找您想要监视的Java进程(当然需要一些正则表达式过滤)。最后,您可以使用以下代码获取您的Java应用程序的内存使用情况(以千字节为单位):

ps -o vsz -p $JAVAPROCESS

我不确定这是否可以与jconsole一起使用,但这是一种监控内存使用情况的方法。


3

我推荐使用Google的cAdvisor项目来监控Docker容器。这样,您就有了一个通用的解决方案来监控Docker容器。只需在Docker容器中运行您的应用程序,并检查如CPU和内存使用情况等指标。这里提供了HTTP API以及Web UI。


0

为了监控Docker中应用程序的内存使用情况,您可以在Docker容器内部启动ejstatd(在启动主容器进程之前,从ejstatd文件夹中调用mvn -Djava.rmi.server.hostname=$HOST_HOSTNAME exec:java -Dexec.args="-pr 2222 -ph 2223 -pv 2224" &),并使用docker run -e HOST_HOSTNAME=$HOSTNAME -p 2222:2222 -p 2223:2223 -p 2224:2224 myimage将这三个端口暴露给Docker主机。

然后,您就可以连接到这个特殊的jstatd守护进程,例如使用JVisualVM,添加一个“远程主机”,将您的Docker主机名指定为“主机名”,并通过将“2222”设置为“端口”来添加一个“自定义jstatd连接”(在“高级设置”中)。

免责声明:我是这个开源工具的作者。


0

0
上面提到的cAdvisor将无法帮助监控容器内运行的Tomcat。您可能想要查看SPM客户端Docker容器,它正是这样做的!它具有用于监视在Docker中运行的许多不同应用程序的代理 - Elasticsearch、Solr、Tomcat、MySQL等:https://github.com/sematext/docker-spm-client

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接