最近在看一個開源的Cache框架,裏面提到使用JMX來查看Cache的命中率以及響應時間等,因而翻了一些JMX的文章,整理了一下。 html
問題:什麼是JMX? java
問題:JMX的架構是什麼樣子的? 緩存
問題:JMX以及Mbean中的 概念都有那些? 架構
問題:如何編寫一個簡單的Standard MBean? 框架
問題:如何編寫一個DynamicMBean? 函數
問題:Open MBean 和Mode MBean是做用是啥? this
問題:按照MBean的規範寫,是否是有點繁瑣,有沒有簡單點的辦法? google
問題:什麼是JMX? spa
JMX(java management extensions)java管理程序擴展,是一個爲應用程序、設備、系統等植入管理功能的框架。 .net
JMX使用了最簡單的一類javaBean,使用有名的MBean,其內部包含了數據信息,這些信息多是程序配置信息、模塊信息、系統信息、統計信息等。MBean能夠操做可讀可寫的屬性、直接操做某些函數。
問題:JMX的架構是什麼樣子的?
問題:JMX使用三層架構,各個層的詳細描述是怎麼樣的?
Probe Level負責資源的檢測(獲取信息),包含MBeans,一般也叫作Instrumentation Level。
The Agent Level 或者叫作MBean Server,是JMX的核心,鏈接這個Mbeans和應用程序。
Remote Management Level經過connectors和adaptors來遠程操做MBeanServer, Applications能夠是你們比較熟悉的控制檯,例如JConsole。
JMX以及Mbean中的 概念都有那些?
一、MBean
一般是一個java類,他提供接口,能夠是這個類具備管理功能。
Standard Mbean是最簡單的MBean,他能管理的資源必須定義在接口中,而後MBean必須實現這個接口,命名必須遵照必定的規範。
1
2
3
4
5
6
|
MBean interface:
一、名字必須以MBean結尾
二、必須與簽名暴漏屬性和操做
MBean implement
一、必須有個名字和接口中"MBean"的前綴相同
二、實現接口中的方法
|
Dynamic Mbean必須實現DynamicMBean,全部的屬性和方法都在運行時定義。
1
2
|
一、必須實現DynamicMBean接口
二、在實現類中實現DynamicMBean中的方法
|
二、MBean Server
管理MBean的一個java類,須要向MBean Server中註冊一個MBean以後,這個MBean纔會具備管理功能,MBeanServer還提供了查詢和註解監聽器的功能,不一樣的JMX實現中MBean Server實現也不一樣。
三、JMX agent
agent是爲了管理一些列的MBean而提供的一系列服務。agent能夠利用protocal adapters(例如HTTP)和connectors使不一樣的客戶端能夠訪問MBean。
問題:如何編寫一個簡單的Standard MBean?
一、編寫MBean的接口:TestMBean.java
定義了屬性的get和set方法以及一個操做方法
1
2
3
4
5
|
public
interface
TestMBean {
public
void
printHelloWorld();
public
String getName();
public
void
setName(String name);
}
|
二、寫一個類實現剛纔的MBean接口Test.java
1
2
3
4
5
6
7
8
9
10
11
12
|
public
class
Test
implements
TestMBean {
private
String name;
public
void
printHelloWorld() {
System.out.println(name+
",welcome to this world."
);
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
}
|
三、編寫一個main函數(將MBean註冊到MBeanServer中)Main.java
1
2
3
4
5
6
7
8
9
10
11
12
|
import
java.lang.management.ManagementFactory;
import
javax.management.MBeanServer;
import
javax.management.ObjectName;
public
class
Main {
public
static
void
main(String[] args)
throws
Exception{
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName name =
new
ObjectName(
"agent:name=test"
);
Test testMBean =
new
Test();
mBeanServer.registerMBean(testMBean, name);
Thread.sleep(
5000000
);
}
}
|
四、經過JConsole來連接java進程,獲取agent信息,經過MBeanServer來操做MBean
問題:如何編寫一個DynamicMBean?
一、搞一個類繼承DynamicMBean( TestDynamic.java)
初始化MBeanMeta 信息,包括Attribute和operation
實現Invoke方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
import
javax.management.Attribute;
import
javax.management.AttributeList;
import
javax.management.AttributeNotFoundException;
import
javax.management.DynamicMBean;
import
javax.management.InvalidAttributeValueException;
import
javax.management.MBeanAttributeInfo;
import
javax.management.MBeanException;
import
javax.management.MBeanInfo;
import
javax.management.MBeanOperationInfo;
import
javax.management.ReflectionException;
public
class
TestDynamic
implements
DynamicMBean {
private
String name =
"iamzhongyong"
;
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
void
printName(){
System.out.println(name);
}
public
Object getAttribute(String attribute)
throws
AttributeNotFoundException, MBeanException,
ReflectionException {
if
(attribute==
null
){
throw
new
AttributeNotFoundException();
}
if
(
"name"
.equalsIgnoreCase(attribute)){
return
getName();
}
throw
new
AttributeNotFoundException();
}
public
void
setAttribute(Attribute attribute)
throws
AttributeNotFoundException, InvalidAttributeValueException,
MBeanException, ReflectionException {
String name = attribute.getName();
Object value = attribute.getValue();
if
(
"name"
.equalsIgnoreCase(name)){
this
.setName(String.valueOf(value));
return
;
}
throw
new
AttributeNotFoundException();
}
public
AttributeList getAttributes(String[] attributes) {
return
null
;
}
public
AttributeList setAttributes(AttributeList attributes) {
return
null
;
}
public
Object invoke(String actionName, Object[] params, String[] signature)
throws
MBeanException, ReflectionException {
if
(
"printName"
.equals(actionName)){
printName();
}
return
null
;
}
public
MBeanInfo getMBeanInfo() {
MBeanAttributeInfo[] dAttributes =
new
MBeanAttributeInfo[] {
new
MBeanAttributeInfo(
"name"
,
"String"
,
"緩存名稱"
,
true
,
true
,
false
)};
MBeanOperationInfo opers[] = {
new
MBeanOperationInfo(
"printName"
,
"print"
,
null
,
"void"
,MBeanOperationInfo.ACTION)};
MBeanInfo info =
new
MBeanInfo(
this
.getClass().getName(),
"TestDynamic"
,
dAttributes,
null
,
opers,
null
);
return
info;
}
}
|
二、main函數編寫(註冊到MBeanServer中)
1
2
3
4
5
6
7
8
9
10
11
12
|
import
java.lang.management.ManagementFactory;
import
javax.management.MBeanServer;
import
javax.management.ObjectName;
public
class
Main {
public
static
void
main(String[] args)
throws
Exception{
MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
ObjectName name =
new
ObjectName(
"agent:name=test"
);
TestDynamic testMBean =
new
TestDynamic();
mBeanServer.registerMBean(testMBean, name);
Thread.sleep(
5000000
);
}
}
|
問題:Open MBean 和Mode MBean是做用是啥?
其實這兩類也是動態的MBean,OpenMBean和其餘MBean不一樣之處在於公共接口的返回值有所限制,只能是基本類型或者openmbean包內的類型。(可能主要考慮到遠端管理系統,可能不具有MBean接口中的特殊的類)
普通的動態的MBean缺乏一些管理系統的支持,例如MBean的狀態持久化或者日誌記錄等,由於JMX廠商提供不一樣的MobleMBean的實現,方便用戶進行操做。
使用pojo-mbean來減小MBean繁瑣的操做
問題:按照MBean的規範寫,是否是有點繁瑣,有沒有簡單點的辦法?
有的,基於POJO-MBean來作JMX,經過註解來實現一些繁瑣的步驟,讓動態MBean不在那麼蛋疼。
pojo-mbean提供了一種基於註解來減小繁瑣的MBean的方式(http://code.google.com/p/pojo-mbean/)。
pojo-mbean沒有依賴任何第三方的包,須要JDK5以上,經過註解標示一個類,是這個類做爲MBean,包括屬性、操做以及參數等。
版本依賴:
1
2
3
4
5
|
<dependency>
<groupId>org.softee</groupId>
<artifactId>pojo-mbean</artifactId>
<version>
1.1
</version>
</dependency>
|
主要原理:
一、在註冊MBeanServer的時候,掃描註解的類文件
二、而後轉換MBean的Meta信息,把相關的信息經過反射完成
三、抽象類實現DynamicMBean
實例代碼以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
import
org.softee.management.annotation.Description;
import
org.softee.management.annotation.MBean;
import
org.softee.management.annotation.ManagedAttribute;
import
org.softee.management.annotation.ManagedOperation;
import
org.softee.management.annotation.Parameter;
import
org.softee.management.helper.MBeanRegistration;
@MBean
(objectName=
"pojo-agent-test:name=HelloWorld"
)
@Description
(
"HelloWorld MBean by pojo-mbean"
)
public
class
HelloWorld {
private
String name ;
private
int
age;
@ManagedOperation
@Description
(
"print the name and age"
)
public
void
print(){
System.out.println(
"name="
+name+
",age="
+age);
}
@ManagedOperation
@Description
(
"increment the age and then return the new age"
)
public
int
incrementAge(
@Parameter
(
"age"
)
int
age){
this
.age =
this
.age+age;
return
this
.age;
}
@ManagedAttribute
@Description
(
"about name"
)
public
String getName() {
return
name;
}
@ManagedAttribute
public
void
setName(String name) {
this
.name = name;
}
@ManagedAttribute
@Description
(
"about age"
)
public
int
getAge() {
return
age;
}
@ManagedAttribute
public
void
setAge(
int
age) {
this
.age = age;
}
/**
* 把MBean註冊到MBeanServer中
* @throws Exception
*/
public
void
initMBeanServer()
throws
Exception{
new
MBeanRegistration(
this
).register();
}
public
static
void
main(String[] args)
throws
Exception{
HelloWorld a =
new
HelloWorld();
a.initMBeanServer();
Thread.sleep(
500000
);
}
}
|
基於此,以後經過MBean來實現一些監控或者管理,就能比較方便了。
參考文章:
http://en.wikipedia.org/wiki/Java_Management_Extensions
http://homepages.thm.de/~hg51/Veranstaltungen/Komponenten-11/Folien/components-jmx.pdf
http://my.oschina.net/zhongl/blog/29075
http://www.blogjava.net/heavensay/archive/2012/09/24/386308.html