什么是JMX
JMX,全稱Java Management Extensions,用於我們管理和監控java應用程序。JMX有以下用途:
- 監控應用程序的運行狀態和相關統計信息。
- 修改應用程序的配置(無需重啟)。
- 狀態變化或出錯時通知處理。
舉個例子,我們可以通過jconsole監控應用程序的堆內存使用量、線程數、類數,查看某些配置信息,甚至可以動態地修改配置。另外,有時還可以利用JMX來進行測試。
本文將介紹以下內容:
- 什么是
JMX; JMX的基礎架構;- 如何使用
JMX。
JMX的基礎架構
首先,看下這種圖:
這里簡單介紹下這三層結構:
| 層次 | 描述 |
|---|---|
| Instrumentation | 主要包括了一系列的接口定義和描述如何開發MBean的規范。在JMX中MBean代表一個被管理的資源實例,通過MBean中暴露的方法和屬性,外界可以獲取被管理的資源的狀態和操縱MBean的行為。 |
| Agent | 用來管理相應的資源,並且為遠端用戶提供訪問的接口。該層的核心是MBeanServer,所有的MBean都要向它注冊,才能被管理。注冊在MBeanServer上的MBean並不直接和遠程應用程序進行通信,他們通過協議適配器(Adapter)和連接器(Connector)進行通信。 |
| Distributed | 定義了一系列用來訪問Agent的接口和組件,包括Adapter和Connector的描述。注意,Adapter 和Connector的區別在於:Adapter是使用某種Internet協議來與 Agent獲得聯系,Agent端會有一個對象 (Adapter)來處理有關協議的細節。比如SNMP Adapter和HTTP Adapter。而Connector則是使用類似RPC的方式來訪問Agent,在Agent端和客戶端都必須有這樣一個對象來處理相應的請求與應答。比如RMI Connector。 |
怎么使用JMX
需求
- 測試本地連接管理
MBean。 - 測試遠程連接管理
MBean,包括代碼實現、啟動參數、啟動參數+配置文件等方式。 - 如何開啟賬號密碼認證。
工程環境
JDK:1.8.0_231
maven:3.6.1
IDE:eclipse 4.12
主要步驟
- 定義
MBean接口,並編寫實現類; - 注冊
MBean到MBeanServe; - 啟動程序;
- 使用
jconsole連接管理該程序。
創建項目
項目類型Maven Project,打包方式jar
引入依賴
入門案例暫時不需要引入外部依賴。
編寫MBean接口
注意,接口名格式必須為:被管理的類的類名+MBean。
public interface UserMBean {
String getName();
void setName(String name);
Integer getAge();
void setAge(Integer age);
String getAddress();
void setAddress(String address);
String sayHello();
}
編寫實現類
這里簡單實現下就行。當屬性被設置時,會在控制台打印相關內容。
public class User implements UserMBean {
private String name;
private Integer age;
private String address;
public String getName() {
return name;
}
public void setName(String name) {
System.err.println("set name to " + name);
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
System.err.println("set age to " + age);
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
System.err.println("set address to " + address);
this.address = address;
}
public String sayHello() {
return "Hello!";
}
}
本地連接
注冊MBean
路徑為test目錄下的cn.zzs.jmx,類名JMXTest。只有將MBean注冊到MBeanServer,MBean才能被管理。MBean的對象名格式為:域名:type=MBean類型,name=MBean名稱。其中,域名和MBean名稱可以隨便取,對象名中除了type,我們還可以自定義其他條目,以方便管理。
注意,為了讓這個程序持續工作,這里強制線程睡眠。
public static void main(String[] args) throws Exception {
// 設置MBean對象名,格式為:“域名:type=MBean類型,name=MBean名稱”
String jmxName = "cn.zzs.jmx:type=user,name=user001";
// 獲得MBeanServer
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
// 創建ObjectName
ObjectName objectName = new ObjectName(jmxName);
// 創建並注冊MBean
server.registerMBean(new User(), objectName);
Thread.sleep(60 * 60 * 1000);
}
測試
啟動程序,打開jconsole(在JDK安裝路徑的bin目錄下),出現如下界面,這時可以看到我們測試的程序:
選擇JMXTest后,點擊連接,這時如果彈窗“安全連接失敗,是否以不安全的方式重試”,這是因為我們沒有開啟ssl加密,可以不去理會它。點擊不安全的連接,即可進入以下頁面:
通過這個窗口我們可以查看程序的堆內存使用量、線程、類等信息,我們再點擊MBean選項卡,可以看到我們編寫的MBean,我們定義的對象名為cn.zzs.jmx:type=user,name=user001,其中cn.zzs.jmx作為第一級目錄,type=user作為第二級目錄,name=user001對應具體的對象,它具備屬性和操作。其中,user的setter和getter方法被合並在了一起。
通過這個界面,我們可以查看和設置user的屬性,或調用它的方法。例如,我先設置name的值,通過程序控制台可以看到該方法被調用了:
接着我再調用sayHello方法:
通過以上例子,可以看到,JMX還是非常有用的,除了查看類的屬性外,我們還可以在不重啟程序的情況下進行配置或執行某些方法。
以上例子中,我們只能在本地訪問JMXTest,接下來介紹如何實現遠程連接。本文介紹三種方式,可根據實際場景選擇:
- 代碼實現;
- 啟動參數配置;
- 啟動參數+文件配置。
遠程連接方式一(代碼實現)
本例子在本地連接的基礎上修改。
開啟遠程連接
注意,這里的localhost最好改為你的IP,不然可能連接不上。
public static void main(String[] args) throws Exception {
// 設置MBean對象名,格式為:“域名:type=MBean類型,name=MBean名稱”
String jmxName = "cn.zzs.jmx:type=user,name=user001";
// 獲得MBeanServer
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
// 創建ObjectName
ObjectName objectName = new ObjectName(jmxName);
// 創建並注冊MBean
server.registerMBean(new User(), objectName);
// 注冊一個端口
LocateRegistry.createRegistry(9999);
// URL路徑的結尾可以隨意指定,但如果需要用Jconsole來進行連接,則必須使用jmxrmi
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
JMXConnectorServer jcs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, server);
jcs.start();
}
測試
打開jconsole,使用遠程連接方式,輸入我們設置好的ip和端口,點擊連接即可:
遠程連接方式二(啟動參數)
本例子在本地連接的基礎上修改。在程序啟動時加入以下啟動參數,也可以實現遠程連接:
-Djava.rmi.server.hostname=<your-ip> // 你的ip
-Dcom.sun.management.jmxremote.port=9999 // 開放端口號
-Dcom.sun.management.jmxremote.local.only=false // 是否只能本地連接
-Dcom.sun.management.jmxremote.ssl=false // 是否使用ssl加密
-Dcom.sun.management.jmxremote.authenticate=false // 是否需要賬號密碼認證
可以看到,我們關閉了ssl加密和賬號密碼認證。
遠程連接方式三(啟動參數+配置文件)
本例子在本地連接的基礎上修改。
啟動參數
在程序啟動時加入以下啟動參數,並結合配置文件,也可以實現遠程連接:
-Dcom.sun.management.config.file=D:/growUp/git_repository/jdk-extend/02-jmx-demo/src/main/resources/config/management.properties // 配置文件路徑
-Djava.rmi.server.hostname=<your-ip>
配置文件
在配置文件中配置以下參數:
# 開放端口號
com.sun.management.jmxremote.port=9999
# 是否只能本地連接
com.sun.management.jmxremote.local.only=false
# 是否使用ssl加密
com.sun.management.jmxremote.ssl=false
# 是否需要賬號密碼認證
com.sun.management.jmxremote.authenticate=false
關於management.propertie的詳細配置,可以在$JRE/lib/management/目錄下找到。其實,當我們在啟動參數中存在以下參數時,默認會去讀取$JRE/lib/management/management.properties的配置文件。
# -Dcom.sun.management.jmxremote.port=<port-number>
# or -Dcom.sun.management.snmp.port=<port-number>
設置賬戶密碼
實際使用中,我們更希望采用安全加密的方式來監控程序,這個時候我們可以設置ssl加密或賬號密碼認證。ssl加密的本文暫時不擴展,這里只介紹如何設置賬號密碼認證。
啟動參數
和上個例子一樣,需要設置如下啟動參數:
-Dcom.sun.management.config.file=D:/growUp/git_repository/jdk-extend/02-jmx-demo/src/main/resources/config/management.properties
-Djava.rmi.server.hostname=<your-ip>
配置文件
配置文件中加入以下內容:
# 開放端口號
com.sun.management.jmxremote.port=9999
# 是否只能本地連接
com.sun.management.jmxremote.local.only=false
# 是否使用ssl加密
com.sun.management.jmxremote.ssl=false
# 是否需要賬號密碼認證
com.sun.management.jmxremote.authenticate=true
# 密碼文件路徑
com.sun.management.jmxremote.password.file=D:/growUp/git_repository/jdk-extend/02-jmx-demo/src/main/resources/config/jmxremote.password
# 權限文件路徑
com.sun.management.jmxremote.access.file=D:/growUp/git_repository/jdk-extend/02-jmx-demo/src/main/resources/config/jmxremote.access
在此之前,我們需要配置好密碼文件和權限文件:
密碼文件
ZhangZiSheng001 root
權限文件
ZhangZiSheng001 readwrite
測試
打開jconsole,選擇遠程連接,並輸入賬號密碼,點擊連接即可:
參考資料
本文為原創文章,轉載請附上原文出處鏈接:https://www.cnblogs.com/ZhangZiSheng001/p/12128915.html
