I want to get tomcat's performance by JMX. Tomcat version is 7 and Java version is 1.7.0_79.
Tomcat runs on the docker's container. The port mapping has set up by the following.
docker run -itd -p 18080:8080 -p 19998:19998 -p 62911:62911 sad_jang2 bash
In the tomcat container, setevn.sh was created in the path, /tomcat_home/bin/ with the following content.
export JAVA_OPTS="
-Xdebug -Xrunjdwp:transport=dt_socket,address=62911,server=y,suspend=n
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=19998
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=172.17.0.16"
I write a simple java code as
JMXServiceURL serviceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + "172.17.0.16"+ ":" + "19998" + "/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(serviceURL, null);
MBeanServerConnection mbsc = connector.getMBeanServerConnection();
and can get related values by JMX.
However, I run this code in my desktop with the docker host's address and 19998 port such as
JMXServiceURL serviceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + "10.70.1.5"+ ":" + "19998" + "/jmxrmi");
The console displayed the following message
java.rmi.ConnectException: Connection refused to host: 172.17.0.16; nested exception is:
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:130)
at javax.management.remote.rmi.RMIServerImpl_Stub.newClient(Unknown Source)
at javax.management.remote.rmi.RMIConnector.getConnection(RMIConnector.java:2432)
at javax.management.remote.rmi.RMIConnector.connect(RMIConnector.java:308)
at javax.management.remote.JMXConnectorFactory.connect(JMXConnectorFactory.java:270)
at utility.GetStatistic.getTomcatStats(GetStatistic.java:84)
at exec.Main.main(Main.java:53)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 9 more
Using the browser to connect the URL http://10.70.1.5:18080 can show the tomcat root's page.
Can anyone give any suggestions? Thanks.
Here's the flags I've successfully used for monitoring my ZooKeeper container via JMX:
So the difference would be this entry
-Dcom.sun.management.jmxremote.rmi.port
which is fix the RMI port to be the same as JMX port.With this I can just
docker run -p 9010:9010 ...
and everything is fine for me.I'm not sure if it's necessary but I would recommend adding this to your additional options
-Djgroups.bind_addr=172.17.0.16
. Also I'm pretty sure that this kind of options should probably go to CATALINA_OPTS and not JAVA_OPTS but that shouldn't make a difference. Another thing that I noticed is that the rmi server host name you defined is different than the one in the JMXServiceURL constructor. I'm no docker expert but shouldn't this be identical?This config worked for me:
The important part was to to configure the rmi server hostname with the local loopback address. If i used 0.0.0.0 i wasn't able to reach the exposed port localy via an SSH Tunnel, with 127.0.0.1 everything worked fine.
Note: if you're running docker inside virtualbox things are different... you have to use the ip which virtualbox gives you here.
This does not work when you run that container in Docker machine - in VirtualBox. I am not sure what kind of address I should add to java.rmi.server.hostname because when I add there external IP of the Docker container I am connecting from my host, it does not work. So basically situation is like HOST ---> (MACHINE --- CONTAINER) and I can not reach it from HOST to CONTAINER.