1. 程式人生 > >JvisualVM 連線遠端伺服器

JvisualVM 連線遠端伺服器

二、jps命令(Java Virtual Machine Process Status Tool)


1、介紹

    jstatd是一個基於RMIRemove Method Invocation)的服務程式,它用於監控基於HotSpotJVM中資源的建立及銷燬,並且提供了一個遠端介面允許遠端的監控工具連線到本地的JVM執行命令。

    jstatd是基於RMI的,所以在執行jstatd的伺服器上必須存在RMI註冊中心,如果沒有通過選項"-p port"指定要連線的埠,jstatd會嘗試連線RMI註冊中心的預設埠。後面會談到如何連線到一個預設的RMI內部註冊中心,如何禁止預設的

RMI內部註冊中心的建立,以及如何啟動一個外部註冊中心。

2、引數選項

    jstatd命令支援如下的選項:

    -nr 如果RMI註冊中心沒有找到,不會建立一個內部的RMI註冊中心。

    -p port RMI註冊中心的埠號,預設為1099

    -n rminame 預設為JStatRemoteHost;如果同一臺主機上同時運行了多個jstatd服務,rminame可以用於唯一確定一個jstatd服務;這裡需要注意一下,如果開啟了這個選項,那麼監控客戶端遠端連線時,必須同時指定hostidvmid,才可以唯一確定要連線的服務,這個可以參看jps章節中列出遠端伺服器上

Java程序的示例。

    -J 用於傳遞jvm選項到由javac呼叫的java載入器中,例如,“-J-Xms48m”將把啟動記憶體設定為48M,使用-J選項可以非常方便的向基於Java的開發的底層虛擬機器應用程式傳遞引數。

3、安全性

    jstatd服務只能監視具有適當的本地訪問許可權的JVM,因此jstatd程序與被監控的JVM必須執行在相同的使用者許可權中。但是有一些特殊的使用者許可權,如基於UNIXTM)為系統的root使用者,它有許可權訪問系統中所有JVM的資源,如果jstatd程序執行在這種許可權中,那麼它可以監視系統中的所有JVM,但是這也帶來了額外的安全問題。

    jstatd服務不會對客戶端進行任何的驗證,因此運行了jstatd服務的JVMs,網路上的任何使用者的都具有訪問許可權,這種暴露不是我們所希望的,因此在啟動jstatd之前本地安全策略必須要加以考慮,特別是在生產環境中或者是在不安全的網路環境中。

    如果沒有其他安全管理器被安裝,jstatd服務將會安裝一個RMISecurityPolicy的例項,因此需要在一個安全策略檔案中指定,該策略檔案必須符合的預設策略實施的策略檔案語法。

    下面的這個示例策略將允許jstatd服務具有JVM全部的訪問許可權:    

  1. grant codebase "file:${java.home}/../lib/tools.jar" {  
  2.    permission java.security.AllPermission;  
  3. };  
    注:此處策略中的java.home,和JAVA_HOME不是一個概念,童鞋們不要搞錯了,此處的java.home指的是JRE的路徑,這個是Java的系統屬性,不需要手工指定,通常是這個jdk下面的jre路徑,即可以認為${java.home}${JAVA_HOME}/jre是等價,如果想檢視這個變數的值,可以任意找一個執行著的Java應用,找到它的PID,然後通過如下jinfo命令檢視就可以檢視到java.home的值:
  1. jinfo ${PID}|grep java.home  

    也可以在Java程式碼中通過如下方式獲取到:

  1. System.out.println(System.getProperty("java.home"))  

    將上面的策略內容拷貝一個檔案中,檔名可以隨意取,為了形象我們將檔名命名為jstatd.all.policy,檔案存放的路徑也可以隨意,只有你當前登陸的使用者具有訪問許可權就可以,然後執行以下命令就可以啟動jstatd服務:

  1. jstatd -J-Djava.security.policy=jstatd.all.policy  

如果是在具有安全限制的環境中,jstatd的策略安全一定要設定得當,並且只允許受信任的伺服器或者網路訪問,以免遭受網路攻擊,如果存在安全隱患,最好不要啟動jstatd服務,就在本地使用jstatjps等工具對JVM進行監控了。

4、示例

4.1、使用內部RMI註冊中心

    下面這個示例演示了通過內部RMI註冊中心啟動jstatd,這個示例假設沒有其它的服務繫結到預設的RMI註冊中心埠(預設埠是1099)。

  1. jstatd -J-Djava.security.policy=jstatd.all.policy  

    注:如果基於預設埠1099RMI註冊中心原來沒有被啟動過,那麼上面執行的命令首先會啟動埠為1099RMI註冊中心,然後再啟動jstatd服務,此時即使jstatd停止了,RMI註冊中心也不會停止;如果是再次執行上面的命令,就不會再次啟動RMI註冊中心,jstatd會直接註冊到註冊中心。

4.2、使用外部的RMI註冊中心

    這個示例演示了使用一個外部的RMI註冊中心來啟動jstatd,如果預設的內部註冊中心已經被啟動了,下面的這個示例就會丟擲“埠1099已經被佔用”的異常,因為它嘗試在1099埠啟動外部RMI註冊中心:

  1. rmiregistry&jstatd -J-Djava.security.policy=all.policy  

    這個示例演示了使用一個外部的RMI註冊中心來啟動jstatd,此註冊中心的埠為2020

  1. rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020  
    這個示例演示了使用一個外部的RMI註冊中心來啟動jstatd,此註冊中心的埠為2020,並且繫結到RMI註冊中心的名為AlternateJstatdServerName
  1. rmiregistry 2020&jstatd -J-Djava.security.policy=all.policy -p 2020 -n AlternateJstatdServerName  

    注:這個埠為2020RMI註冊中心,我們會在jps章節中使用到。

4.3、禁止內部RMI註冊中心的建立

    這個示例演示了jstatd在啟動的時候,如果沒有找到預設的RMI註冊中心,也不會建立預設的註冊中心。這個示例中如果沒有RMI註冊中心在執行,此示例就會報錯,如果存在就會正常執行:   

  1. jstatd -J-Djava.security.policy=all.policy -nr  

4.4、開啟RMI日記記錄

    這個示例演示的是jstatd執行在開啟了日誌記錄功能的RMI註冊中,這個對於問題查詢或監控服務狀態非常有用:

  1. jstatd -J-Djava.security.policy=all.policy -J-Djava.rmi.server.logCalls=true