Using Visualvm to Connect to a Remote Jstatd Instance Through a Firewall

Using VisualVM to connect to a remote jstatd instance through a firewall

Instead of creating a firewall rule every time I run jstatd (because it annoyingly chooses a new random port each time), I got it to work with SSH tunnels.

First I ran jstatd on the server to find which ports I needed to tunnel. That is done by (in my case) first creating a policy file called tools.policy with the following contents:

grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};

Then running the following command: jstatd -J-Djava.security.policy=tools.policy

Then I determined the random port jstatd was using by running sockstat | grep jstat (may need to use netstat instead on Linux, I'm not sure).

Then lets say the random port is 55663, I created two SSH tunnels on my local machine, one for the standard jstatd port 1099 and the other for 55663 by running the following commands in two terminal windows (haven't done this on Windows, but I'm pretty sure putty can do it):

ssh -L 1099:localhost:1099 login_name@host_name

ssh -L 55663:localhost:55663 login_name@host_name

Once the two tunnels were open, I opened VisualVM and right clicked on the "Local" machine on the left side and chose "Add jstatd Connection". I clicked the "Add Default" button on the right and made sure the port was set to 1099. I hit the "OK" button to save it and immediately saw my remote Java processes show up in the "Local" section.

VisualVM over ssh

You either need to run jstatd on the remote side, or specify a JMX connection using host:port.

Jstatd:

jstatd -J-Djava.security.policy=permissions.txt [-p port]

After that: add a remote connection to the target machine, and on the properties of that remote connection configure the jstatd connection.

(permissions.txt contains for example this:

grant {
permission java.security.AllPermission;
};

Edit: (Answer to comment)

  1. ssh -D 9696 me@remote, and run jstatd as above on the remote command line. If you want jstatd to be on a different port than the default 1099, use the -p argument to jstatd.

  2. run visualvm.exe -J-Dnetbeans.system_socks_proxy=localhost:9696 -J-Djava.net.useSystemProxies=true on the local machine

  3. in visual vm: add new remote connection, and specify remote as host and the port for jstatd (1099 for default, or what you specified with -p when running jstatd)

    You should now see the processes on the remote side in visualvm

Can visualvm connect automatically via JMX to a remote process?

Unfortunately there is no way to assign random JMX port to the remote application. You can start your remote application with

-Dcom.sun.management.jmxremote.port=<fixed port>
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

and VisualVM will be able to read this configuration via Jvmstat (provide by jstatd) and open JMX connection to your remote application automatically. So you need to assign fixed port(s) to your remote application(s). Once you have it, everything will work fine and VisualVM will automatically connect to your application via JMX (in fact it will combine data from both Jvmstat and JMX).

remote profiling neo4j using visualvm

What happen if you try to run jstatd with full path?

sudo -u neo4j /usr/lib/jvm/java-8-oracle/bin/jstatd -p 8888 -J-Djava.security.policy=/home/ubuntu/tools.policy -J-Djava.rmi.server.hostname=neo4j_ip_address

How to connect Spring Boot application remotely in Visual VM?

We need to specify the remote IP ADDRESS and expose the listening PORT while running the jar.

Syntax:

java 
-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.port=<PORT>
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Djava.rmi.server.hostname=<IP_ADDRESS>
-Dcom.sun.management.jmxremote.rmi.port=<PORT>
-jar app-1.0.0-SNAPSHOT.jar

Example: Listening port is 6001 and available for remote ip address 192.168.0.23

java -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=6001 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.0.23 -Dcom.sun.management.jmxremote.rmi.port=6001 -jar app-1.0.0-SNAPSHOT.jar 

For More details about set up Visual VM https://github.com/M-Thirumal/installation_guide/blob/master/visualVm/visualvm_remote_set_up.md

Remote monitoring with visualvm and JMX

Please use the following JVM options :

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.59.99

In the Jconsole use the following to connect:

service:jmx:rmi:///jndi/rmi://192.168.59.99:9010/jmxrmi

Debugging VisualVM remote connection

Set the hostname property before the VM starts:

java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9191 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Djava.rmi.server.hostname=the.public.ip \
-jar program.jar

Add the relevant rules to your security group.



Related Topics



Leave a reply



Submit