JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » EJB / 其它Java EE 討論區  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
己加入精華區
by koji at 2008-09-24 23:56
本主題所含的標籤
無標籤
作者 JMX應用篇 [精華]
Fenris





發文: 68
積分: 4
於 2008-09-24 03:40 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
JMX 真的超冷門,相關文章很久沒更新了 Disapproved
小弟寫了三篇文章希望可以幫大家多了解 JMX

p.s. 主要是跟 spring 的整合,所以對 spring 也要有所了解

JMX(1) - 管理自己的 server
用各種 AP servers 時大家都習慣在 web console 設定各種的 resources
但自己架 RMI server 或 socket server 時通常也希望有一個 console 可以設定管理
在以前要額外寫一個管理介面非常的麻煩不過 JDK 1.5 之後整合了 JMX,可以透過註冊 mbean 到 mbean server,並由 JMX console 管理
這篇文章不講複雜的 JMX 定義,而是以 spring 設定 c3p0 datasource、log4j 和 quartz schedule jobs 的 mbeans
讓大家實際體驗一下 JMX 的好處

1. 設定 log4j mbean
1
2
<bean id="log4jMBean"
    class="org.apache.log4j.jmx.HierarchyDynamicMBean" />


2. 設定 c3p0 datasource
先看一下 datasource 在 spring 的設定
1
2
3
4
5
6
7
8
9
10
11
12
<bean id="dataSource"
    class="com.mchange.v2.c3p0.ComboPooledDataSource"
    destroy-method="close">
    <property name="driverClass" value="com.mysql.jdbc.Driver" />
    <property name="jdbcUrl"
        value="jdbc:mysql://localhost:3306/test" />
    <property name="user" value="root" />
    <property name="password" value="fenriswolf" />
    <property name="initialPoolSize" value="1" />
    <property name="minPoolSize" value="1" />
    <property name="maxPoolSize" value="10" />
</bean>


接下來是 mbean 的設定
但有一點要注意,雖然 c3p0 有支援 JMX,不過只支援 local mbean server
意思是如果要註冊自己的 datasource mbean 到 JBoss、Weblogic 等 mbean server 上是不行的
少了整合的彈性
要解決這個問題有兩個步驟:
a. 新增 c3p0.properties 到根目錄,加入
1
2
com.mchange.v2.c3p0.management.ManagementCoordinator=com.mchange.v2.c3p0.management.
NullManagementCoordinator

意思是不使用 JMX 設定,因為要由 spring 控管

b. 加入以下 xml 到 spring 設定檔
1
2
3
4
5
6
<bean
    class="com.mchange.v2.c3p0.management.DynamicPooledDataSourceManagerMBean">
    <constructor-arg ref="dataSource" />
    <constructor-arg value="server:name=c3p0" />
    <constructor-arg ref="mbeanServer" />
</bean>

constructor第一個參數是 datasource 的 reference
第二個參數是 mbean object name
第三個參數是 mbean server 的 reference

3. 設定 quartz schedule jobs
jobdetails 跟 triggers 的設定有點多就不列出來了,請看程式下載區的完整範例
quartz 1.6 也支援 JMX,可透過 org.quartz.scheduler.jmx.export=true 來啟動
不過支援並不完整,只能看到 scheduler 的資訊,triggers 和 jobdetails 的資訊看不到
我自定 com.fw.jmx.quartz.SchedulerMBean 來解決這個問題(請下載quartzmbean.jar)
為了系統的穩定性,故除了 scheduler 可以執行 start, standby, shutdown 之外
triggers 和 jobdetails 都是不可更改及執行的,有需要的人可自行更改
下面是 mbean 的設定
1
2
3
4
<bean id="schedulerMBean" class="com.fw.jmx.quartz.SchedulerMBean">
    <constructor-arg ref="scheduler" />
    <constructor-arg ref="triggers" />
</bean>

constructor第一個參數是 scheduler 的 reference
第二個參數是 trigger list 的 reference

4. export mbeans
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<bean id="mbeanServer"
    class="org.springframework.jmx.support.MBeanServerFactoryBean">
    <property name="locateExistingServerIfPossible" value="true" />
</bean>
 
<bean id="exporter"
    class="org.springframework.jmx.export.MBeanExporter">
    <property name="beans">
        <map>
            <entry key="server:name=log4j" value-ref="log4jMBean" />
            <entry key="server:name=FWScheduler"
                value-ref="schedulerMBean" />
        </map>
    </property>
    <property name="server" ref="mbeanServer" />
</bean>

mbean server 由 java.lang.management.ManagementFactory.getPlatformMBeanServer() 取得
MBeanExporter 則是註冊 mbeans 到 mbean server
entry key 是 mbean object name
value-ref 是上面定義的 mbean bean name
這邊註冊的 mbeans 只有兩個,因為 c3p0 會由 DynamicPooledDataSourceManagerMBean 來註冊

5. 執行程式
為了可以監控 mbeans 要在 java 指令後加上 -Dcom.sun.management.jmxremote 的參數
如 : java -Dcom.sun.management.jmxremote com.fw.jmx.TestMain
注意 : 這個參數是為了在 local 監控才需要,如用 mx4j HttpAdaptor(請看附錄)則不需要

6. 執行 jmx console
在命令列模式執行 jconsole

jconsole 抓到剛執行的程式,直接點選 Connect



選取 MBeans tab 會列出所有已註冊的 mbeans,上方有兩個 tabs,Attributes 和 Operations
以 FWScheduler 為例,可以看執行的狀況及啟動或停止所有的 schedules

附錄1
執行 jconsole 一定要在 local 裝 JDK 並不是那麼方便
想提供網頁供 administrator 設定可用 mx4j HttpAdaptor
方法很簡單
a. 多加兩個 bean 到 spring 設定檔
1
2
3
4
5
6
7
8
<bean id="xsltProcessor"
    class="mx4j.tools.adaptor.http.XSLTProcessor" />
 
<bean id="httpAdaptor"
    class="mx4j.tools.adaptor.http.HttpAdaptor">
    <property name="processor" ref="xsltProcessor" />
    <property name="port" value="9001" />
</bean>


b. 在 MBeanExporter 裡註冊
1
2
3
4
<entry key="server:name=HttpAdaptor"
    value-ref="httpAdaptor" />
<entry key="server:name=XSLTProcessor"
    value-ref="xsltProcessor" />


c. 更改啟動的 main method 加入
1
2
3
4
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
        "appContext.xml");
HttpAdaptor httpAdaptor = (HttpAdaptor) context.getBean("httpAdaptor");
httpAdaptor.start();


d. 連到 http://localhost:9001 就可以看到設定頁面啦

有點醜,有需要可自行更改 XSLTProcessor

附錄2
第二個選擇是用 JDMK HtmlAdaptorServer(需下載 jdmkrt.jar)
a. 加入 spring 設定檔
1
2
3
4
<bean id="htmlAdapter"
    class="com.sun.jdmk.comm.HtmlAdaptorServer">
    <property name="port" value="9001" />
</bean>


b. 在 MBeanExporter 裡註冊
1
2
<entry key="server:name=htmlAdapter"
    value-ref="htmlAdapter" />


c. 更改啟動的 main method 加入
1
2
3
4
5
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
        "appContext.xml");
HtmlAdaptorServer htmlAdapter = (HtmlAdaptorServer) context
        .getBean("htmlAdapter");
htmlAdapter.start();


d. 連到 http://localhost:9001 就可以看到設定頁面啦

這比 mx4j 好看多了

執行環境
JDK 1.5.0_11(因為 1.6 的 jconsole 太醜了)
spring 2.5
log4j 1.2.14
c3p0 0.9.1.2
quartz 1.6
mx4j 3.0.2

參考資料
JMX Tutorial
Spring JMX
log4j 1.2
c3p0
Quartz JMX Management
MX4J
Java Dynamic Management Kit

程式下載
appContext.xml
c3p0.properties
MyBean.java
TestMain.java
quartzmbean.jar(原始檔在此)
jdmkrt.jar


Fenris edited on 2008-09-24 23:08
reply to postreply to post
玩人生online,選賺錢職業,進朋友公會,打家庭副本,衝公司聲望,解客戶任務,買把妹座騎,點戀愛天賦,修虎爛技能,集3C套裝
作者 Re:JMX應用篇 [Re:Fenris]
Fenris





發文: 68
積分: 4
於 2008-09-24 22:59 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
JMX(2) - 自訂 mbeans
在複雜的系統裡需要監控的資源不是只有 log, datasources, schedule jobs 那麼簡單
還會有自訂的一些資源
JMX 提供了 Standard MBean 和 Dynamic MBean 兩種實作方式
不過這篇文章會以 spring 來定義及控管自訂的 mbeans

1. export services to mbeans
假設在系統中已經有一個 ResourceBundleService 來存取 env.properties,程式如下
ResourceBundleService.java
1
2
3
4
5
public interface ResourceBundleService {
    public String getString(String key);
 
    public String getBaseName();
}


ResourceBundleServiceImpl.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ResourceBundleServiceImpl implements ResourceBundleService,
        InitializingBean {
    private String baseName;
    private ResourceBundle resourceBundle;
 
    public String getString(String key){
        return resourceBundle.getString(key);
    }
    
    public void afterPropertiesSet() throws Exception {
        resourceBundle = ResourceBundle.getBundle(baseName);
    }
 
    public String getBaseName() {
        return baseName;
    }
 
    public void setBaseName(String baseName) throws Exception {
        this.baseName = baseName;
        afterPropertiesSet();
    }
}


在 spring 的定義
1
2
3
4
<bean id="resourceBundleService"
    class="com.fw.jmx.ResourceBundleServiceImpl">
    <property name="baseName" value="env" />
</bean>


註冊成 mbean 的方法非常簡單,只要在 MBeanExporter 裡直接設定就好了
1
2
3
4
5
6
7
8
9
10
<bean id="exporter"
    class="org.springframework.jmx.export.MBeanExporter">
    <property name="beans">
        <map>
            <entry key="server:name=resourceBundleService"
                value-ref="resourceBundleService" />
        </map>
    </property>
    <property name="server" ref="mbeanServer" />
</bean>


接下來就是看執行結果



既然這麼容易,為什麼 log4j、c3p0 datasource、quartz schedule job 不用這種方式設定???
原因有三個
a. 最重要的一點,call setBaseName method 並不會更新 ResourceBundle。
一般來說,執行時期不會去更改系統參數,所以要特別注意
b. spring 用 reflection 的方式抓出 ResourceBundleServiceImpl 所有的 methods,包括不需要用到的 methods 如 afterPropertiesSet()
c. 畫面顯示的資訊並不完整,如 methods 沒有說明,參數以 p1、p2 顯示

第一個問題要改 setBaseName method,加入 reload propertiles file 的動作
1
2
3
4
public void setBaseName(String baseName) throws Exception {
    this.baseName = baseName;
    afterPropertiesSet();
}


其他的問題可由設定 Assembler 解決

2. 定義 Assembler
spring 定義了好幾種 assemblers 可供設定
a. SimpleReflectiveMBeanInfoAssembler : 這是 spring 預設的 assembler,結果如上面顯示就不多做介紹

b. InterfaceBasedMBeanInfoAssembler : 可過濾不需要的 methods
先定義一個新的 interface,少了 afterPropertiesSet method
1
2
3
4
5
6
7
public interface ResourceBundleServiceMBean {
    public String getString(String key);
 
    public String getBaseName();
 
    public void setBaseName(String baseName);
}

這裡不延用 ResourceBundleService interface
因為 setBaseName method 應該要由 administrator 來設定
而不是由 developer 透過程式控制

在 spring 中 assembler 的定義
1
2
3
4
5
6
7
8
9
10
<bean id="assembler"
  class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler">
    <property name="interfaceMappings">
        <props>
            <prop key="resourceBundleService">
                com.fw.jmx.ResourceBundleServiceMBean
            </prop>
        </props>
    </property>
</bean>


在 MBeanServerFactoryBean 加入 assembler 的參數
1
<property name="assembler" ref="assembler" />


c. MetadataMBeanInfoAssembler : 用 annotation 的方式定義,可設定最完整的資訊
annotation 的用法蠻直覺的就不多做解釋
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
@ManagedResource(description = "ResourceBundleService MBean")
public class ResourceBundleServiceImpl implements ResourceBundleService,
        InitializingBean {
    private String baseName;
    private ResourceBundle resourceBundle;
 
    @ManagedOperation(description="Gets a string for the given key")
    @ManagedOperationParameters({
      @ManagedOperationParameter(name = "key", 
                                 description = "the key for the desired string")})
    public String getString(String key) {
        return resourceBundle.getString(key);
    }
 
    public void afterPropertiesSet() throws Exception {
        resourceBundle = ResourceBundle.getBundle(baseName);
    }
 
    @ManagedAttribute(defaultValue="env")
    public String getBaseName() {
        return baseName;
    }
 
    @ManagedAttribute(description="the base name of the resource bundle")
    public void setBaseName(String baseName) throws Exception {
        this.baseName = baseName;
        afterPropertiesSet();
    }
}


接下來是 spring 的定義
1
2
3
4
5
6
7
<bean id="attributeSource"
  class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource" />
    
<bean id="assembler"
    class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
    <property name="attributeSource" ref="attributeSource" />
</bean>


1.5 jconsole 的結果,滑鼠移上去就會顯示 tooltip


這是 1.6 jconsole 的結果,所有資訊比較一目了然


執行環境
JDK 1.5.0_11(因為 1.6 的 jconsole 太醜了)
spring 2.5
log4j 1.2.14
c3p0 0.9.1.2
quartz 1.6
mx4j 3.0.2

參考資料
JMX Tutorial
Spring JMX
log4j 1.2
c3p0
Quartz JMX Management
MX4J
Java Dynamic Management Kit

程式下載
ResourceBundleService.java
ResourceBundleServiceImpl.java
ResourceBundleServiceMBean.java
appContext.xml


Fenris edited on 2008-09-24 23:08
reply to postreply to post
玩人生online,選賺錢職業,進朋友公會,打家庭副本,衝公司聲望,解客戶任務,買把妹座騎,點戀愛天賦,修虎爛技能,集3C套裝
作者 Re:JMX應用篇 [Re:Fenris]
Fenris





發文: 68
積分: 4
於 2008-09-24 23:08 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
JMX(3) - 與 weblogic 9 整合
很多 JMX 的文章會強調可整合各種不同的管理方式和介面到單一的介面
但實際上可能剛好相反,把自訂的 mbeans 整合到既有的平台是比較簡單的方式
以下就介紹如何把前兩章提到的 mbeans 註冊到 weblogic 9 的 mbean server
以及如何在 weblogic console 中存取 mbeans
以下方法在 weblogic 10 也是適用的
p.s. datasource, mx4j 等會由 weblogic 取代,故在範例裡會拿掉

1. 前置工作
a. 下載 weblogic spring framework support library(程式下載區會提供)
b. 把 spring-ext-server.jar 放到 DomainHome/console-ext 下
c. 把 spring-ext-client.jar 放到 webapp 的 WEB-INF/lib 下

2. lookup weblogic mbean server
更改 spring xml,把 mbean server 換成以下這個
1
2
3
4
<bean id="mbeanServer"
    class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jmx/runtime" />
</bean>


3. 新增 weblogic mediator
1
2
3
4
<bean id="mediator"
    class="com.interface21.wl9.jmx.mediator.Mediator">
    <property name="applicationName" value="jmxweb" />
</bean>

注意 : applicationName 要跟 war 檔名稱一致

4. 更改 MBeanExporter 設定
a. 註冊 mediator
1
2
3
<entry
    key="spring.framework:type=Mediator,application=jmxweb"
    value-ref="mediator" />

注意 : application=XXX 要跟 war 檔名稱一致

b. 將 mediator 註冊為 listener
1
2
3
4
5
<property name="listeners">
    <list>
        <ref local="mediator" />
    </list>
</property>


5. 設定 web.xml
這部分跟一般用 spring web framework 是一樣的
1
2
3
4
5
6
7
8
9
10
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:appContext.xml</param-value>
</context-param>
 
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>


接下就是直接 deploy 看結果啦
在 管理介面最後會多一個 tab,點進去就可以看到所有註冊的 mbean,不過 weblogic 會把 mediator 拿掉


點選各 mbean 的連結可看詳細資料,使用上跟 jconsole 是一樣的


執行環境
JDK 1.5.0_06
weblogic 9.2
spring 2.5
log4j 1.2.14
quartz 1.6

參考資料
JMX Tutorial
Spring JMX
log4j 1.2
Quartz JMX Management
Weblogic Spring Framework Support 2.0.2

程式下載
appContext.xml
spring-ext-server.jar
spring-ext-client.jar
jmx web 範例


reply to postreply to post
玩人生online,選賺錢職業,進朋友公會,打家庭副本,衝公司聲望,解客戶任務,買把妹座騎,點戀愛天賦,修虎爛技能,集3C套裝
» JWorld@TW »  EJB / 其它Java EE 討論區

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8