我正在尝试使用JMX访问在docker容器内运行的应用程序。
这与this question类似,当docker镜像内的端口映射到图像外部的相同端口时,该解决方案可以正常工作。但是,我有时想将端口映射到不同的端口。
我在托管应用程序中设置这些属性。
-Dcom.sun.management.jmxremote.port=9832
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.local.only=false
-Dcom.sun.management.jmxremote.rmi.port=9832
-Djava.rmi.server.hostname=192.168.99.100
-Djava.rmi.server.logCalls=true
当docker容器将端口9832映射到9832时,这可以正常工作。我可以通过JConsole或我们自己的应用程序连接。如果端口被映射到另一个端口,那么我无法从JConsole或我们的应用程序访问该应用程序。
我怀疑一个或两个端口号需要是外部端口(就像java.rmi.server.hostname
一样是外部地址,而不是内部地址)。但是,它失败了所有四种端口号组合。
其中两个组合不会从服务器生成日志输出。一个(我忘了哪个)产生这个输出:
Feb 09, 2016 10:35:54 PM org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl start
INFO: AMQ221001: Apache ActiveMQ Artemis Message Broker version 1.1.0 [nodeID=7a6e038e-cf7d-11e5-b566-31dc437b2d1a]
HTTP Server started at http://0.0.0.0:8161
Feb 09, 2016 10:36:06 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[], long, java.rmi.dgc.Lease)]
Feb 09, 2016 10:36:08 PM sun.rmi.transport.Transport serviceCall
FINE: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1] exception:
java.rmi.NoSuchObjectException: no such object in table
at sun.rmi.transport.Transport.serviceCall(Transport.java:177)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Feb 09, 2016 10:40:24 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(2)-192.168.99.1: [192.168.99.1: sun.rmi.transport.DGCImpl[0:0:0, 2]: void clean(java.rmi.server.ObjID[], long, java.rmi.dgc.VMID, boolean)]
另一个产生此输出。
HTTP Server started at http://0.0.0.0:8161
Feb 09, 2016 10:14:13 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1: sun.management.jmxremote.SingleEntryRegistry[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
Feb 09, 2016 10:14:17 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1: sun.management.jmxremote.SingleEntryRegistry[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
Feb 09, 2016 10:14:17 PM sun.rmi.server.UnicastServerRef logCall
FINER: RMI TCP Connection(1)-192.168.99.1: [192.168.99.1: sun.management.jmxremote.SingleEntryRegistry[0:0:0, 0]: java.rmi.Remote lookup(java.lang.String)]
鉴于这些失败,我怀疑一个或两个端口属性的使用方式有时需要是内部端口,有时需要是外部端口。这意味着当端口映射到不同的位置时,无法进行JMX访问。
我可以通过telnet 192.168.99.100 <mapped port>
访问映射端口,所以我知道映射正在运行。
答案 0 :(得分:0)
我遇到了同样的问题,并且连续三天都放弃了,我做的解决方案虽然不好,但是可以用。因此,我的解决方案是:我没有在JMX连接上设置固定端口并使用其他外部端口将其映射,而是在docker-compose.yml上创建了一个名为JMX_MNG_PORT的环境变量。
...
ports:
- '9011:9011'
...
environment:
- JMX_MNG_PORT=9011
...
然后我在docker-entrypoint.sh上配置了JAVA_OPTS变量以接收JMX_MNG_PORT。
...
JAVA_OPTS=$JAVA_OPTS -Dcom.sun.management.jmxremote.port=${JMX_MNG_PORT}
JAVA_OPTS=$JAVA_OPTS -Dcom.sun.management.jmxremote.rmi.port=${JMX_MNG_PORT}
...
现在,在每个要配置的容器(docker-compose.yml)上,我只需要配置JMX_MNG_PORT并使用THE SAME NUMBER公开端口。
记住,我不知道为什么,但是如果您使用另一个端口,那么在jmxremote.port和jmxremote.rmi.port上配置的端口将无法工作。
我希望它能解决像我这样的人的情况。