如何使用JMX來管理程序?

什么是JMX

JMX,全稱Java Management Extensions,用于我們管理和監控java應用程序。JMX有以下用途:

  1. 監控應用程序的運行狀態和相關統計信息。
  2. 修改應用程序的配置(無需重啟)。
  3. 狀態變化或出錯時通知處理。

舉個例子,我們可以通過jconsole監控應用程序的堆內存使用量、線程數、類數,查看某些配置信息,甚至可以動態地修改配置。另外,有時還可以利用JMX來進行測試。

本文將介紹以下內容:

  1. 什么是JMX;
  2. JMX的基礎架構;
  3. 如何使用JMX。

JMX的基礎架構

首先,看下這種圖:

JMX的基礎架構

這里簡單介紹下這三層結構:

層次 描述
Instrumentation 主要包括了一系列的接口定義和描述如何開發MBean的規范。在JMXMBean代表一個被管理的資源實例,通過MBean中暴露的方法和屬性,外界可以獲取被管理的資源的狀態和操縱MBean的行為。
Agent 用來管理相應的資源,并且為遠端用戶提供訪問的接口。該層的核心是MBeanServer,所有的MBean都要向它注冊,才能被管理。注冊在MBeanServer上的MBean并不直接和遠程應用程序進行通信,他們通過協議適配器(Adapter)和連接器(Connector)進行通信。
Distributed 定義了一系列用來訪問Agent的接口和組件,包括AdapterConnector的描述。注意,AdapterConnector的區別在于:Adapter是使用某種Internet協議來與 Agent獲得聯系,Agent端會有一個對象 (Adapter)來處理有關協議的細節。比如SNMP AdapterHTTP Adapter。而Connector則是使用類似RPC的方式來訪問Agent,在Agent端和客戶端都必須有這樣一個對象來處理相應的請求與應答。比如RMI Connector。

怎么使用JMX

需求

  1. 測試本地連接管理MBean。
  2. 測試遠程連接管理MBean,包括代碼實現、啟動參數、啟動參數+配置文件等方式。
  3. 如何開啟賬號密碼認證。

工程環境

JDK:1.8.0_231

maven:3.6.1

IDE:eclipse 4.12

主要步驟

  1. 定義MBean接口,并編寫實現類;
  2. 注冊MBeanMBeanServe;
  3. 啟動程序;
  4. 使用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目錄下),出現如下界面,這時可以看到我們測試的程序:

jconsole_01.png

選擇JMXTest后,點擊連接,這時如果彈窗“安全連接失敗,是否以不安全的方式重試”,這是因為我們沒有開啟ssl加密,可以不去理會它。點擊不安全的連接,即可進入以下頁面:

jconsole_02.png

通過這個窗口我們可以查看程序的堆內存使用量、線程、類等信息,我們再點擊MBean選項卡,可以看到我們編寫的MBean,我們定義的對象名為cn.zzs.jmx:type=user,name=user001,其中cn.zzs.jmx作為第一級目錄,type=user作為第二級目錄,name=user001對應具體的對象,它具備屬性和操作。其中,usersettergetter方法被合并在了一起。

jconsole_03.png

通過這個界面,我們可以查看和設置user的屬性,或調用它的方法。例如,我先設置name的值,通過程序控制臺可以看到該方法被調用了:

jconsole_04.png

接著我再調用sayHello方法:

jconsole_05.png

通過以上例子,可以看到,JMX還是非常有用的,除了查看類的屬性外,我們還可以在不重啟程序的情況下進行配置或執行某些方法。

以上例子中,我們只能在本地訪問JMXTest,接下來介紹如何實現遠程連接。本文介紹三種方式,可根據實際場景選擇:

  1. 代碼實現;
  2. 啟動參數配置;
  3. 啟動參數+文件配置。

遠程連接方式一(代碼實現)

本例子在本地連接的基礎上修改。

開啟遠程連接

注意,這里的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和端口,點擊連接即可:

jconsole_06.png

遠程連接方式二(啟動參數)

本例子在本地連接的基礎上修改。在程序啟動時加入以下啟動參數,也可以實現遠程連接:

-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,選擇遠程連接,并輸入賬號密碼,點擊連接即可:

jconsole_07.png

參考資料

相關源碼請移步:https://github.com/ZhangZiSheng001/02-jmx-demo

本文為原創文章,轉載請附上原文出處鏈接://www.wcdoq.com/ZhangZiSheng001/p/12128915.html

posted @ 2020-01-01 15:02  子月生  閱讀(...)  評論(...編輯  收藏