
一般来说,管理系统会将同一物理分布或者功能类似的 SubAgent 分组成一组,由一个共用的 Agent 加以管理。在这个 Agent 里封装了 1 和 2 的功能。
JMX 和管理系统
JMX 既是 Java 管理系统的一个标准,一个规范,也是一个接口,一个框架。图 2 展示了 JMX 的基本架构。
图 2. JMX 构架
和其它的资源系统一样,JMX 是管理系统和资源之间的一个接口,它定义了管理系统和资源之间交互的标准。>javax.management.MBeanServer 实现了 Agent 的功能,以标准的方式给出了管理系统访问 JMX 框架的接口。而 >javax.management.MBeans 实现了 SubAgent 的功能,以标准的方式给出了 JMX 框架访问资源的接口。而从类库的层次上看,JMX 包括了核心类库 >java.lang.management 和 >javax.management 包。>java.lang.management 包提供了基本的 VM 监控功能,而 >javax.management 包则向用户提供了扩展功能。
JMX 的基本框架
JMX 使用了 Java Bean 模式来传递信息。一般说来,JMX 使用有名的 MBean,其内部包含了数据信息,这些信息可能是:应用程序配置信息、模块信息、系统信息、统计信息等。另外,MBean 也可以设立可读写的属性、直接操作某些函数甚至启动 MBean 可发送的 notification 等。MBean 包括 Standard,MXBean,Dynamic,Model,Open 等几种分类,其中最简单是标准 MBean 和 MXBean,而我们使用得最多的也是这两种。MXBean 主要是 >java.lang.management 使用较多,将在下一节中介绍。我们先了解其他一些重要的 MBean 的种类。
标准 MBean
标准 MBean 是最简单的一类 MBean,与动态 Bean 不同,它并不实现 >javax.management 包中的特殊的接口。说它是标准 MBean, 是因为其向外部公开其接口的方法和普通的 Java Bean 相同,是通过 lexical,或者说 coding convention 进行的。下面我们就用一个例子来展现,如何实现一个标准 MBean 来监控某个服务器 ServerImpl 状态的。ServerImpl 代表了用来演示的某个 Server 的实现:
package standardbeans;
public class ServerImpl {
public final long startTime;
public ServerImpl() {
startTime = System.currentTimeMillis();
}
}
|
package standardbeans;
public class ServerMonitor implements ServerMonitorMBean {
private final ServerImpl target;
public ServerMonitor(ServerImpl target){
this.target = target;
}
public long getUpTime(){
return System.currentTimeMillis() - target.startTime;
}
}
|
package standardbeans;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
public class Main {
private static ObjectName objectName ;
private static MBeanServer mBeanServer;
public static void main(String[] args) throws Exception{
init();
manage();
}
private static void init() throws Exception{
ServerImpl serverImpl = new ServerImpl();
ServerMonitor serverMonitor = new ServerMonitor(serverImpl);
mBeanServer = MBeanServerFactory.createMBeanServer();
objectName = new ObjectName("objectName:id=ServerMonitor1");
mBeanServer.registerMBean(serverMonitor,objectName);
}
private static void manage() throws Exception{
Long upTime = (Long) mBeanServer.getAttribute(objectName,
"upTime");
System.out.println(upTime);
}
}
|
package dynamicbeans;
import javax.management.*;
import java.lang.reflect.*;
public class ServerMonitor implements DynamicMBean {
private final ServerImpl target;
private MBeanInfo mBeanInfo;
public ServerMonitor(ServerImpl target){
this.target = target;
}
//实现获取被管理的 ServerImpl 的 upTime
public long upTime(){
return System.currentTimeMillis() - target.startTime;
}
//javax.management.MBeanServer 会通过查询 getAttribute("Uptime") 获得 "Uptime" 属性值
public Object getAttribute(String attribute) throws AttributeNotFoundException,
MBeanException, ReflectionException {
if(attribute.equals("UpTime")){
return upTime();
}
return null;
}
//给出 ServerMonitor 的元信息。
public MBeanInfo getMBeanInfo() {
if (mBeanInfo == null) {
try {
Class cls = this.getClass();
//用反射获得 "upTime" 属性的读方法
Method readMethod = cls.getMethod("upTime", new Class[0]);
//用反射获得构造方法
Constructor constructor = cls.getConstructor(new Class[]
{ServerImpl.class});
//关于 "upTime" 属性的元信息:名称为 UpTime,只读属性(没有写方法)。
MBeanAttributeInfo upTimeMBeanAttributeInfo = new MBeanAttributeInfo(
"UpTime", "The time span since server start",
readMethod, null);
//关于构造函数的元信息
MBeanConstructorInfo mBeanConstructorInfo = new MBeanConstructorInfo(
"Constructor for ServerMonitor", constructor);
//ServerMonitor 的元信息,为了简单起见,在这个例子里,
//没有提供 invocation 以及 listener 方面的元信息
mBeanInfo = new MBeanInfo(cls.getName(),
"Monitor that controls the server",
new MBeanAttributeInfo[] { upTimeMBeanAttributeInfo },
new MBeanConstructorInfo[] { mBeanConstructorInfo },
null, null);
} catch (Exception e) {
throw new Error(e);
}
}
return mBeanInfo;
}
public AttributeList getAttributes(String[] arg0) {
return null;
}
public Object invoke(String arg0, Object[] arg1, String[] arg2)
throws MBeanException,
ReflectionException {
return null;
}
public void setAttribute(Attribute arg0) throws AttributeNotFoundException,
InvalidAttributeValueException, MBeanException, ReflectionException {
return;
}
public AttributeList setAttributes(AttributeList arg0) {
return null;
}
}
|
其它动态 MBean
package modelmbean;
public class Server {
private long startTime;
public Server() { }
public int start(){
startTime = System.currentTimeMillis();
return 0;
}
public long getUpTime(){
return System.currentTimeMillis() - startTime;
}
}
|
package modelmbean;
import javax.management.*;
import javax.management.modelmbean.*;
public class Main {
public static void main(String[] args) throws Exception{
MBeanServer mBeanServer = MBeanServerFactory.createMBeanServer();
RequiredModelMBean serverMBean =
(RequiredModelMBean) mBeanServer.instantiate(
"javax.management.modelmbean.RequiredModelMBean");
ObjectName serverMBeanName =
new ObjectName("server: id=Server");
serverMBean.setModelMBeanInfo(getModelMBeanInfoForServer(serverMBeanName));
Server server = new Server();
serverMBean.setManagedResource(server, "ObjectReference");
ObjectInstance registeredServerMBean =
mBeanServer.registerMBean((Object) serverMBean, serverMBeanName);
serverMBean.invoke("start",null, null);
Thread.sleep(1000);
System.out.println(serverMBean.getAttribute("upTime"));
Thread.sleep(5000);
System.out.println(serverMBean.getAttribute("upTime"));
}
private static ModelMBeanInfo getModelMBeanInfoForServer(ObjectName objectName)
throws Exception{
ModelMBeanAttributeInfo[] serverAttributes =
new ModelMBeanAttributeInfo[1];
Descriptor upTime =
new DescriptorSupport(
new String[] {
"name=upTime",
"descriptorType=attribute",
"displayName=Server upTime",
"getMethod=getUpTime",
});
serverAttributes[0] =
new ModelMBeanAttributeInfo(
"upTime",
"long",
"Server upTime",
true,
false,
false,
upTime);
ModelMBeanOperationInfo[] serverOperations =
new ModelMBeanOperationInfo[2];
Descriptor getUpTimeDesc =
new DescriptorSupport(
new String[] {
"name=getUpTime",
"descriptorType=operation",
"class=modelmbean.Server",
"role=operation"
});
MBeanParameterInfo[] getUpTimeParms = new MBeanParameterInfo[0];
serverOperations[0] = new ModelMBeanOperationInfo("getUpTime",
"get the up time of the server",
getUpTimeParms,
"java.lang.Long",
MBeanOperationInfo.ACTION,
getUpTimeDesc);
Descriptor startDesc =
new DescriptorSupport(
new String[] {
"name=start",
"descriptorType=operation",
"class=modelmbean.Server",
"role=operation"
});
MBeanParameterInfo[] startParms = new MBeanParameterInfo[0];
serverOperations[1] = new ModelMBeanOperationInfo("start",
"start(): start server",
startParms,
"java.lang.Integer",
MBeanOperationInfo.ACTION,
startDesc);
ModelMBeanInfo serverMMBeanInfo =
new ModelMBeanInfoSupport(
"modelmbean.Server",
"ModelMBean for managing an Server",
serverAttributes,
null,
serverOperations,
null);
//Default strategy for the MBean.
Descriptor serverDescription =
new DescriptorSupport(
new String[] {
("name=" + objectName),
"descriptorType=mbean",
("displayName=Server"),
"type=modelmbean.Server",
"log=T",
"logFile=serverMX.log",
"currencyTimeLimit=10" });
serverMMBeanInfo.setMBeanDescriptor(serverDescription);
return serverMMBeanInfo;
}
|
1.serverMBean.setModelMBeanInfo(getModelMBeanInfoForServer(serverMBeanName)); 2.serverMBean.setManagedResource(server, "ObjectReference"); |
第二步指出了 ServerMBean 管理的对象,也就是说,从元数据中得到的 Method 将施加在哪个 Object 上。需要指出的是 >setManagedResource(Object o, String type); 中第二个参数是 Object 类型,可以是 "ObjectReference"、"Handle"、"IOR"、"EJBHandle" 或 "RMIReference"。目前 SE 中的实现只支持 "ObjectReference"。笔者认为后面几种类型是为了将来 JMX 管理对象扩展而设定的,可能将来 Model Bean 不仅可以管理 Plain Java Object(POJO),还可能管理 Native Resource, 并给诸如 EJB 和 RMI 对象的管理提供更多的特性。
Model Bean 与普通动态 Bean 区别在于它的元数据类型 ModelMBeanInfo 扩展了前者的 MBeanInfo,使得 ModelMBeanOperationInfo、ModelMBeanConstructor_Info、ModelMBeanAttributeInfo 和 ModelMBeanNotificationInfo 都有一个额外的元数据:>javax.management.Descriptor,它是用来设定 Model Bean 策略的。数据的存储是典型的 "key-value" 键值对。不同的 Model Bean 实现,以及不同的 MBeanFeatureInfo 支持不同的策略特性。下面我们就以 Attribute 为例,看一下 RequiredModelBean 支持的策略。
评论 {{userinfo.comments}}
{{child.content}}



{{question.question}}
提交