使用jvisualVm監控本地和遠端的jvm
jvisualVm是jdk自帶的視覺化監控工具,功能很強大,可安裝各種擴充套件外掛。本篇不打算講解如果使用詳細的功能,只講在windows環境怎麼監控本地和遠端(一般是無介面的linux系統)的java程序。
1、在遠端機器上新增許可權策略檔案
在伺服器{JAVA_HOME}/bin目錄建立檔案:jstatd.all.policy(名字隨便,符合*.policy即可), 檔案內容為:
grant codebase "file:${java.home}/../lib/tools.jar" { permission java.security.AllPermission; };
2、修改伺服器 hosts 檔案中的 IP 地址
要使Java VisualVM 成功連線到遠端伺服器上,伺服器端應該在 /etc/hosts 檔案中把本機地址設為本機的 IP 地址。使用 hostname -i 命令檢視,如果顯示的是 127.0.0.1 或者與本機實際 IP 不一致的話,需要把 /etc/hosts 檔案中相應的地址改為本機實際 IP 。
3、執行 jstatd 守護程式
在jstatd.all.policy 當前目錄執行
nohup $JAVA_HOME/bin/jstatd -J-Djava.security.policy=jstatd.all.policy &
如果需要RMI 日誌功能的話,還可以在啟動引數中加入 -J-Djava.rmi.server.logCalls=true 。
nohup $JAVA_HOME/bin/jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.logCalls=true &
可以自己制定jstatd的埠,加-p <port> 引數,預設埠為1099.
我擦,報錯了·····
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 看看埠是不是被佔用了!如果被佔用換一個埠。
jstatd -J-Djava.security.policy=jstatd.all.policy -p 2099
4、使用本地jvisualVm連線遠端主機
進過1、2、3步驟,最後我們使用window本地的jvisualVm連線配置好的遠端主機,這個很簡單,不介紹。
但是問題來了,第3部的時候連線配置卻怎麼也沒有看到遠端機器的java程序,排查這個問題,請確定你的一下步驟是否成功
(1)服務端機器jstatd服務是否開啟:使用jps檢視是否有jstatd程序。
(2)確定本地機器是否連線上遠端伺服器,使用netstat -anp | grep jstatd程序ID檢視網路連線,是否有你本地機器IP
配置並啟動jvisualvm
直接命令列啟動jvisualvm或{JAVA_HOME}/bin目錄,找到jvisualvm.exe程式,雙擊開啟。
如果重新指定了jstatd埠,選擇高階設定修改埠,如下圖:
通過以上方式連線伺服器發現一個問題,不能監控CPU 。提示我們建立 JMX ,建立 JMX 提示要求埠號。(JMX: Java Management Extensions ,即 Java 管理擴充套件 , 是一個為應用程式、裝置、系統等植入管理功能的框架。 JMX可以跨越一系列異構作業系統平臺、系統體系結構和 網路傳輸協議,靈活的開發無縫整合的系統、網路和服務管理應用。而 Visual VM是通過 JMX 來和遠端 Java 應用聯絡的 )。
5、jvm程序啟動項配置
以tomcat為例:
伺服器的 tomcat 配置 jvm 啟動引數。 在 tomcat 的 catalina.sh 中新增如下引數:
JAVA_OPTS="-Djava.rmi.server.hostname=192.168.0.216 -Dcom.sun.management.jmxremote.port=1100 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
注:
-Dcom.sun.management.jmxremote.port :1100 這個是配置遠端 connection 的埠號的,要確定這個埠沒有被佔用
-Dcom.sun.management.jmxremote.ssl=false 指定了 JMX 是否啟用 ssl
-Dcom.sun.management.jmxremote.authenticate=false 指定了JMX 是否啟用鑑權(需要使用者名稱,密碼鑑權)
前面是固定配置,是 JMX 的遠端服務許可權的
-Djava.rmi.server.hostname :這個是配置 server 的 IP 的
如果同時配置了JMX,可以在新增JMX連線如下圖:
新增後如圖所示: