Clark To Do The blog of Clark

Spring配置JDMK中的HtmlAdaptorServer

1.简介

JDMK(Java动态管理组件)是一种Java技术, 为开发和设计基于JMX的应用提供了一组API与工具集. 这些应用通常被称为智能代理, 因为它们在通信层之上提供了一层抽象, 同时也会提供一个Swing或SWT的图形界面.

HtmlAdaptorServer是JDMK包内的类, 它自Sun JMX 1.2.1实现中被引入. 作为一个HTML的服务器, 它可以通过浏览器来管理代理中所有的MBean. 此HTML协议适配器是作为一个动态的MBean被实现的.

2.HtmlAdaptorServer

HtmlAdaptorServer是JDMK包内的类,可以通过指定一个URL在浏览器中访问JMX代理, 格式例如:

http://host:port

此处:

  • host是代理所在的主机名.
  • port是HTML服务器所配置的端口. (默认: 8082)

HTML协议适配器为管理代理中的MBean提供了如下HTML页面:

  • 代理视图: 提供了所有在代理制已注册的MBean的名称列表.
  • 代理管理页面: 代理中的注册器与注销器.
  • MBean视图: 读写MBean的属性并在代理中的MBean上执行相关操作.

当HTML协议适配器启动时, 会创建一个TCP/IP的套接字并监听客户端连接.

套接字的默认端口号是8082, 也可通过如下方式指定其他端口:

  • 在对象构造器内指定
  • 启动适配器之前, 通过setPort方法指定

默认对象名称被定义为com.sun.jdmk.ServiceName.DOMAIN 和 com.sun.jdmk.ServiceName.HTML_ADAPTOR_SERVER.

当客户端尝试连接时, HtmlAdaptorServer会创建一个线程来接收和处理此客户端随后的所有请求. 客户端的数量可以通过maxActiveClientCount属性加以限制, 默认值是10.

当HtmlAdaptorServer关闭时, 所有当前的HTTP连接都会被中断(一些请求可能会被突然终止), 同时TCP/IP的套接字也会被关闭.

HtmlAdaptorServer也支持用户认证. 添加/删除用户认证信息方法可被用来管理用户及其对应的认证信息. HTML服务器使用”基础认证模式”来认证客户端连接.

Maven中可以通过添加jmxtools来添加对HtmlAdaptorServer的依赖:

<dependency>
    <groupId>com.sun.jdmk</groupId>
    <artifactId>jmxtools</artifactId>
    <version>1.2.1</version>
</dependency>

简单的Java代码:

package com.clarkdo.tinyproject;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;

import com.sun.jdmk.comm.HtmlAdaptorServer;

public class HtmlServer {
  public static void main(String[] args) {
    try {
      MBeanServer server = MBeanServerFactory.createMBeanServer("test");
      HtmlAdaptorServer adapter = new HtmlAdaptorServer();
      ObjectName httpName = new ObjectName("system:name=http");
      server.registerMBean(adapter, httpName);
      adapter.setPort(9292);
      adapter.setMaxActiveClientCount(5);
      adapter.start();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

3.Spring中HtmlAdaptorServer的配置

目前大量的项目中都是用了Spring来管理Bean直接的依赖关系, 还是可以很大程度上减少工作量和代码耦合性的. 因此也建议通过Spring来配置HtmlAdaptorServer.

配置的大致步骤如下:

  • 配置HtmlAdaptorServer(指定端口及用户认证信息等)
  • 配置MBeanServer
  • 配置MBeanExporter(在MBeanServer中注册HtmlAdaptorServer, 以及其他相关信息, 下文中会详细说明)

1.配置HtmlAdaptorServer

配置HtmlAdaptorServer时候, 通过指定init-method=”start”与destroy-method=”stop”使服务器启动或关闭时, 自动启动或关闭htmlAdaptor.

同时通过构造函数参数注入端口与用户认证信息.

<bean id="htmlAdaptor" class="com.sun.jdmk.comm.HtmlAdaptorServer"
      init-method="start" destroy-method="stop">
    <constructor-arg index="0" value="${jmx.htmlAdaptor.port}" />
    <constructor-arg index="1">
        <bean id="authInfo" class="com.sun.jdmk.comm.AuthInfo">
            <property name="login" value="${jmx.htmlAdaptor.username}" />
            <property name="password" value="${jmx.htmlAdaptor.password}" />
        </bean>
    </constructor-arg>
</bean>

2.配置MBeanServer

建议通过MBeanServerFactoryBean进行配置实现, 它包含以下属性:

  • locateExistingServerIfPossible: 在创建之前会尝试定位是否存在正在运行的MBeanServer
  • agentId: 要定位的MBeanServer的代理id
  • defaultDomain: MBeanServer使用的默认域
  • registerWithFactory: 是否通过MBeanServerFactory注册MBeanServer
  <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean" >
      <property name="locateExistingServerIfPossible" value="true" />
  </bean>

3.配置MBeanExporter

MBeanExporter可以将任意Spring容器管理的Bean暴露给JMX, 而不需要定义任何JMX信息.

MBeanExporter相关属性:

  • beans: 要暴露给JMX管理的Bean, 以JMX名作为键值.
  • jmxAttributeSource: 此属性并不是MBeanExporter内的直接属性, 但是assembler与namingStrategy都依赖此属性, 配置为AnnotationJmxAttributeSource, 用于解析注解.
  • assembler: 通过Bean的Type和Key获取模型信息, 利用jmxAttributeSource解析注解, 来读取元数据.
  • namingStrategy: 用于查询对象名称, 以便于注册资源.
  • autodetect: 表示是否自动检测当前exporter所在BeanFactory内的MBean, 默认关闭.
  • server: 指定所有Bean需要被注册在其中的MBeanServer.

以下配置会检测使用@ManagedResource及@ManagedOperation配置的Bean, 并将其纳入HTML适配器展现中.

<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
    <property name="beans">
        <map>
            <entry key="adaptor:name=htmlAdaptor" value-ref="htmlAdaptor" />
        </map>
    </property>
    <property name="assembler" ref="assembler"/>
    <property name="namingStrategy" ref="namingStrategy"/>
    <property name="autodetect" value="true"/>
    <property name="server" ref="mbeanServer" />
</bean>

<bean id="jmxAttributeSource"
      class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>

<!-- will create management interface using annotation metadata -->
<bean id="assembler"
      class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
    <property name="attributeSource" ref="jmxAttributeSource"/>
</bean>

<!-- will pick up the ObjectName from the annotation -->
<bean id="namingStrategy"
      class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
    <property name="attributeSource" ref="jmxAttributeSource"/>
</bean>
@ManagedResource(objectName="CLARK:name=HtmlServerBean",  description="Example for HtmlAdaptorServer")
public class HtmlServerBean {

    @ManagedOperation(description="First Method for testing HtmlAdaptorServer")
    public void methodOne(String param) {

    }

    @ManagedOperation(description="Secon Method for testing HtmlAdaptorServer")
    public void methodTwo(String param1, String param2) {

    }
}
comments powered by Disqus