'RMI'에 해당되는 글 1건

Spring + Apache Mina + JMX :: 2009/01/22 11:31

네트워크 어플리케이션 프레임워크인 Apache Mina를 이용하여 소켓 서버를 구현할 수 있다. Mina는 Spring DI를 이용하여 쉽게 인테그레이션 될 수 있고, 또한 Spring에서 지원하는 JMX 기능을 사용하여 서버에 등록된 Bean들을 모니터링 및 관리를 할 수 있다.

1. Apache Mina의 IoHandler를 구현한 클래스와 소켓서버의 설정을 아래와 같이 설정한다.
<!-- java.net.InetSocketAddress objects by Spring -->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="customEditors">
    <map>
      <entry key="java.net.SocketAddress">
        <bean class="org.apache.mina.integration.spring.InetSocketAddressEditor" />
      </entry>
    </map>
  </property>
</bean>

<!-- The IoHandler implementation -->
<bean id="ioHandler" class="net.java2go.server.MyIoHandler" />

<!-- thread pool -->
<bean id="threadModel"
    class="org.apache.mina.integration.spring.ExecutorThreadModelFactoryBean">
  <property name="serviceName" value="MyService" />
  <property name="executor">
    <bean class="org.apache.mina.integration.spring.ThreadPoolExecutorFactoryBean">
      <property name="corePoolSize" value="10" />
      <property name="maxPoolSize" value="30" />
      <property name="keepAliveSeconds" value="30" />
    </bean>
  </property>
</bean>

<!-- The IoAcceptor which binds to port 8099 -->
<bean id="ioAcceptor"
class="org.apache.mina.integration.spring.IoAcceptorFactoryBean"> <property name="target"> <bean class="org.apache.mina.transport.socket.nio.SocketAcceptor" /> </property> <property name="bindings"> <list> <bean class="org.apache.mina.integration.spring.Binding"> <property name="address" value="8099" /> <property name="handler" ref="ioHandler" /> <property name="serviceConfig"> <bean class="org.apache.mina.transport.socket.nio.SocketAcceptorConfig"> <property name="reuseAddress" value="true" /> <property name="threadModel" ref="threadModel" /> </bean> </property> </bean> </list> </property> </bean>

2. Apache Mina의 IoServiceManager 및 기타 JMX를 통해 노출하고자하는 Bean을 등록한다. 그리고 Spring JMX MBeanExporter 설정을 통해 해당 Bean을 노출한다. 여기서는 RMI를 이용하였고, 이 경우 RMI Registry에 대한 설정도 추가해 준다.
<bean id="ioServiceManager"
    class="org.apache.mina.integration.jmx.IoServiceManager">
  <constructor-arg index="0" ref="ioAcceptor" />
</bean>

<bean id="mbeanServer"
    class="org.springframework.jmx.support.MBeanServerFactoryBean">
  <property name="locateExistingServerIfPossible" value="true" />
  <!--<property name="defaultDomain" value="server" />-->
</bean>

<bean id="serverConnector"
    class="org.springframework.jmx.support.ConnectorServerFactoryBean"
    depends-on="rmiRegistry">
  <property name="objectName" value="connector:name=rmi" />
  <property name="serviceUrl" 
      value="service:jmx:rmi://localhost/jndi/rmi://localhost:1099/server" />
</bean>

<bean id="rmiRegistry"
    class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
  <property name="port" value="1099" />
</bean>

<bean id="mbeanExporter" class="org.springframework.jmx.export.MBeanExporter">
  <property name="beans">
    <map>
      <entry key="server:name=ioService" value-ref="ioServiceManager" />
      <!--<entry key="server:name=myServiceBean" value-ref="myServiceBean" />-->
    </map>
  </property>
  <property name="registrationBehaviorName" value="REGISTRATION_REPLACE_EXISTING" />
  <property name="server">
    <ref local="mbeanServer" />
  </property>
</bean>

3. JMX를 통해 MBean에 접속하려는 서버에 방화벽이 설치되어 있는 경우, JMX/RMI Connector를 위한 Port를 명시적으로 지정할 필요가 있다. 그렇지 않으면 시스템에서 랜덤하게 지정된 Port를 사용하게 되는데 방화벽이 설치된 경우 임의 Port를 사용할 수 없으므로 접속이 불가능하게 된다. 다음과 같이 JMX/RMI Connector를 위한 포트를 지정해 준다. (참고: RMI Connector와 Repository 포트는 동일해도 됨).
<property name="serviceUrl" 
  value="service:jmx:rmi://localhost:1098/jndi/rmi://localhost:1099/server" />

4. JMX 모니터링 도구를 사용하여 JMX 서버에 접속하여 모니터링을 수행한다. JMX 접속 주소는 Spring 설정에서 노출한 serviceUrl이 되며, 다음은 JDK에 포함되어 있는 JColsole을 이용하여 모니터링을 수행한 화면이다.

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지

사용자 삽입 이미지