2011年8月28日 星期日

JMX & Spring

用Spring要產生一個MBean並且註冊到MBeanServer是蠻容易的。基本上,幾乎只要使用XML設定就可以了。作法如下:
  1. 確定有使用context的XML schema。在XML設定檔中加入
    <context:mbean-server id="mbeanServer">
    , 其中id是用來表示該mbean server。這個xml tag是Spring 2.5以後多的,可以簡化設定。當然也可以用傳統的spring bean的定義方式:
    <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>
  2. 加入RMI registry的宣告,一般來說使用JMX的remoting,在沒特別處理的情況,都是以RMI protocol來做通訊:
    <bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean"><property name="port" value="1099"/></bean>
  3. 宣告MBean的connector server,這是用來讓外部可以連線到MBeanServer:
    <bean id="serverConnector" class="org.springframework.jmx.support.ConnectorServerFactoryBean">
    <property name="threaded" value="true"/>
    <property name="objectName" value="connector:name=rmi"/>
    <property name="serviceUrl" value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxrmi"/>
    </bean>
    ,其中,service url的定義跟JMX的定義跟格式是一樣的。
  4. 最後就是宣告MBeanExporter,然後指定要export的bean跟ObjectName:
    <bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
    <property name="server" ref="mbeanServer"/>
    <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING"/>
    <property name="beans">
    <map>
    <entry key="heero:name=msService" value-ref="mobileSuitService"/>
    </map>
    </property>
    </bean>
而連線的方式,可以用一般標準的JMX client連線方式,或是使用Spring的方式。Spring的方式就是透過MBeanProxyFactoryBean來產生MBean的proxy。
最後,有幾點注意:
  1. mbean server的宣告,如果不是使用<context:mbean-server/>,則如果再產生mbean server發現已經有同id的server存在時,還是會繼續產生。所以可能會造成混淆。所以必須額外加上
    <property name="locateExistingServerIfPossible" value="true"/>
  2. 在實際上使用發現,如果有使用Hibernate跟Spring JMX support,則用傳統bean定義的方式產生mbean server,會一直警告該server已經存在。
  3. 經測試發現,當mbean server啟動時,立刻去連線會失敗,但是若是等待幾秒則OK
  4. 根據Spring文件,MBeanExporter是不可以lazy initialization的。所以必須設定為lazy-init="false"
這是最簡單容易的作法之一,在幾乎不改code的情況下就可以產生JMX的支援。當然Spring也有其他的作法,像是使用annotation。詳情就參考Spring文件。

沒有留言: