9.使用jvisualVm監控本地,線上jvm

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監控時遇到的,希望能能幫助到大家!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章