修改Dockerfile文件,添加jmx参数,如下:
ENV JAVA_OPTS="\
-Dcom.sun.management.jmxremote=true \
-Dcom.sun.management.jmxremote.rmi.port=28000 \
-Dcom.sun.management.jmxremote.port=28000 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Djava.rmi.server.hostname=172.16.20.208"
EXPOSE 80
EXPOSE 28000
ENTRYPOINT java ${JAVA_OPTS} -jar /app.jar
其中-Djava.rmi.server.hostname为docker主机的地址,而非docker容器的地址,测试发现此地址必须加,否则无法启动JMX服务,不在Docker容器中启动是可以不带这个参数的。
容器启动后可以通过jvisualvm工具查看,
1、远程- 添加远程主机,输入地址172.16.20.208
2、添加JMX连接,补充28000端口
3、连接到远程服务器
如何需要查看MBean熟悉,还需下载VisualVM-MBeans插件。VisualVM-MBeans更新最新版本的时候经常失败,最好是手动下载一个相对较新的版本,从本地安装。
VisualVM-MBeans插件下载地址:
https://visualvm.github.io/archive/downloads/release136/com-sun-tools-visualvm-modules-mbeans_1.nbm
上面的方法虽然已实现JMX的监控,但是将JMX服务绑定IP地址写在Dockerfile中,要部署到不同的机器上就很不方便了。为了解决上面问题,我们可以将JMX启动相关参数通过docker run指令传递给ENTRYPOINT。调整Dockerfile如下:
...
EXPOSE 80
ENTRYPOINT ["/bin/sh", "-c","java $0 -jar /app.jar"]
...
$0在这里占个位置,接收docker run传过来的参数。
docker run指令格式如下:
docker run <image-name> <command> arg1 arg2
docker run <image-name> arg1 arg2
JMX_OPTS="-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.rmi.port=28000 \
-Dcom.sun.management.jmxremote.port=28000 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.local.only=false \
-Djava.rmi.server.hostname=172.16.20.208"
docker run -d -p 19092:80 -p 28000:28000 --name <CONTAINER_NAME> <IMAGE_NAME> "$JMX_OPTS";
docker run <image_name>
后第一个输入通常是一个命令,所以是 $0,如果有其他参数,用$@表示,由于JMX_OPTS参数中有换行,必须加上双引号,否则参数传递不完整。