jvisualVm是jdk自带的可视化监控工具,功能很强大,可安装各种扩展插件。本篇不打算讲解如果使用详细的功能,只讲在windows环境怎么监控本地和远端(一般是无界面的linux系统)的java进程。
首先安装jdk,打开的{JAVA_HOME}/bin目录,找到
jvisualvm.exe程序,双击打开,如图:
如上图,左边是本地和远程的java进程,右边是该工具的使用指南。
本地的java进程直接显示在工具里,如图笔者本地有两个java进程,双击进入即可。
一般情况下,我们通常是要监控远程主机的java进程,已排查线上问题,那这时候就要用到远程监控功能了。这里主要介绍通过jstatd工具开启远程主机访问接口。
1、在远程机器上添加权限策略文件
在服务器
{JAVA_HOME}/bin目录建立文件:jstatd.all.policy(名字随便,符合*
.policy即可), 文件内容为:
grant codebase
"file:${java.home}/../lib/tools.jar"
{
permission java.security.AllPermission;
};
2、开启远程访问功能
执行命令:jstatd -J-Djava.security.policy=jstatd.all.policy(后台执行:nohup jstatd -J-Djava.security.policy=jstatd.all.policy &)
我擦,报错了·····
Could not bind /JStatRemoteHost to RMI Registry
java.rmi.ServerException: RemoteException occurred in server thread; nested exception is:
java.rmi.UnmarshalException: error unmarshalling arguments; nested exception is:
java.lang.ClassNotFoundException: sun.jvmstat.monitor.remote.RemoteHost (no security manager: RMI class loader disabled)
at sun.rmi.server.UnicastServerRef.oldDispatch(UnicastServerRef.java:419)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:267)
at sun.rmi.transport.Transport$1.run(Transport.java:177)
at sun.rmi.transport.Transport$1.run(Transport.java:174)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:553)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:808)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:667)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:273)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:251)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:377)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at java.rmi.Naming.rebind(Naming.java:177)
at sun.tools.jstatd.Jstatd.bind(Jstatd.java:57)
at sun.tools.jstatd.Jstatd.main(Jstatd.java:143)
不用担心,这种错误是你的端口被占用了,
jstatd默认启动1099端口,使用netstat -anp | grep 1099 看看端口是不是被占用了!
[ root@VM_200_30 bin]# netstat -anp | grep 1099
tcp 0 0 :::1099 :::* LISTEN 12674/java
果然是,那这时候指定一下没有被使用的端口就好了,执行命令:(我这里使用
2099)
jstatd -J-Djava.security.policy=jstatd.all.policy -p 2099
3、使用本地jvisualVm连接远程主机
进过1、2步骤,最后我们使用window本地的jvisualVm连接配置好的远程主机,这个很简单,不介绍。
但是问题来了,第3部的时候连接配置却怎么也没有看到远程机器的java进程,排查这个问题,请确定你的一下步骤是否成功
(1)服务端机器jstatd服务是否开启:使用jps查看是否有jstatd进程。
(2)确定本地机器是否连接上远程服务器,使用netstat -anp | grep jstatd进程ID查看网络连接,是否有你本地机器IP
(3)jvisualVm远程连接IP和端口是否填写正确
经过以上步骤如果你确定没有问题,那么很可能是是的服务端hosts配置不对,解决办法:
(1)用hostname -i 命令查看返回的IP地址是不是127.0.0.1,如果不是的话则说明是其它原因造成,无需再往下看了,否则进行入第2步。
(2)打开/etc下的hosts文件,将其中的“127.0.0.1 机器名”改成"你机器的IP 机器名"。或者添加一个也可以
例如:将127.0.0.1 ubuntuServer,改成192.168.1.99 ubuntuServer
(3)重新启动jstatd进程。
如果在本地用jps 192.168.1.99可以看到远程java进程则说明成功了,此时你应该可以在VisualVM中通过jstatd方式连接远程主机了
好了,以上问题都在我使用jvisualVm监控时遇到的,希望能能帮助到大家!!
jstatd命令介绍: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jstatd.html