必须实现javax.management.DynamicMBean接口,所有的属性,方法都在运行时定义.
对于standard MBeans, jmx agent为之创建了metadata;而对于dynamic mbean,开发者必须自己提供被管理资源的metadata.虽然增加了难度,但是获得了灵活性。
DynamicMBean接口的定义:
getMBeanInfo(): MBeanInfo
getAttribute( attribute:String ): Object
getAttributes( attributes:String[] ): AttributeList
setAttribute( attribute:Attribute ): void
setAttributes( attributes:AttributeList ): AttributeList
invoke( actionName:String, params:Object[],signature:String[] ): Object
从概念上来说, dynamic MBean也有属性和方法,但是他们并不是通过方法直接暴露出来.
相反,在运行状态时,通过getMBeanInfo()方法,可以得到MBeanInfo对象.
这个对象包含了属性名称和类型列表, 以及方法和参数的列表,还有其他一些管理信息等metadata.
getAttribute
传入参数为一个属性名称,返回为对应的值对象
getAttributes
传入参数为属性名称列表,返回为对应的Attribute对象列表
setAttribute and setAttributes
传入参数为name-value pairs,把这些值写到对应的属性中.
setAttribute没有返回参数, setAttributes返回AttributeList
invoke方法
让管理程序调用任何dynamic MBean暴露出来的方法.
必须提供调用的方法名称和要传入的参数以及它们的类型.
行为:
当在JMX agent里注册时候, dynamic MBean和standard MBean是同样被对待的。
管理程序首先通过getMBeanInfo函数获得管理接口,得到属性和方法的名称.然后程序可以调用getters,setters和invoke方法.
在standard MBean中,MBean server使用自省发现调用的接口。而在动态MBean中,MBean server将自我描述的功能让给了getMBeanInfo()函数。开发者在此函数中,定义MBean的信息,MBean server并不会测试和验证这些信息。所以,开发者必须要保证它们的正确性。
有个问题,因为接口方法都是通过getMBeanInfo函数获得的,所以是动态的,连续的调用函数返回的数据可能不相同。这就会带来一些一致性的问题。
做个example:
import java.lang.reflect.Constructor;
import java.util.Iterator;
import javax.management.*;
public class SimpleDynamic implements DynamicMBean {
/*
*私有变量
*/
private String state = "initial state";
private int nbChanges = 0;
private int nbResets = 0;
private String dClassName = this.getClass().getName();
private String dDescription = "Simple implementation of a dynamic MBean.";
private MBeanAttributeInfo[] dAttributes = new MBeanAttributeInfo[2];
private MBeanConstructorInfo[] dConstructors = new MBeanConstructorInfo[1];
private MBeanOperationInfo[] dOperations = new MBeanOperationInfo[1];
private MBeanInfo dMBeanInfo = null;
public SimpleDynamic() {
// 建立辅助信息
buildDynamicMBeanInfo();
}
public Object getAttribute(String attribute_name)
throws AttributeNotFoundException, MBeanException,
ReflectionException {
// 检查属性是否为空
if (attribute_name == null) {
throw new RuntimeOperationsException(new IllegalArgumentException(
"Attribute name cannot be null"),
"Cannot invoke a getter of " + dClassName
+ " with null attribute name");
}
// 检查已知属性,调用已知方法
if (attribute_name.equals("State")) {
return getState();
}
if (attribute_name.equals("NbChanges")) {
return getNbChanges();
}
// 如果属性不可识别,抛出异常
throw (new AttributeNotFoundException("Cannot find " + attribute_name
+ " attribute in " + dClassName));
}
public void setAttribute(Attribute attribute)
throws AttributeNotFoundException, InvalidAttributeValueException,
MBeanException, ReflectionException {
if (attribute == null) {
throw new RuntimeOperationsException(new IllegalArgumentException(
"Attribute cannot be null"), "Cannot invoke a setter of "
+ dClassName + " with null attribute");
}
String name = attribute.getName();
Object value = attribute.getValue();
if (name == null) {
throw new RuntimeOperationsException(new IllegalArgumentException(
"Attribute name cannot be null"),
"Cannot invoke the setter of " + dClassName
+ " with null attribute name");
}
if (name.equals("State")) {
if (value == null) {
try {
setState(null);
} catch (Exception e) {
throw (new InvalidAttributeValueException(
"Cannot set attribute " + name + " to null"));
}
} else {
try {
if ((Class.forName("java.lang.String"))
.isAssignableFrom(value.getClass())) {
setState((String) value);
} else {
throw (new InvalidAttributeValueException(
"Cannot set attribute " + name + " to a "
+ value.getClass().getName()
+ " object, String expected"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
// 由于"NbChanges" 属性是只读的,所以抛出异常
else if (name.equals("NbChanges")) {
throw (new AttributeNotFoundException("Cannot set attribute "
+ name + " because it is read-only"));
} else {
throw (new AttributeNotFoundException("Attribute " + name
+ " not found in " + this.getClass().getName()));
}
}
public AttributeList getAttributes(String[] attributeNames) {
if (attributeNames == null) {
throw new RuntimeOperationsException(new IllegalArgumentException(
"attributeNames[] cannot be null"),
"Cannot invoke a getter of " + dClassName);
}
AttributeList resultList = new AttributeList();
if (attributeNames.length == 0)
return resultList;
for (int i = 0; i < attributeNames.length; i++) {
try {
Object value = getAttribute((String) attributeNames[i]);
resultList.add(new Attribute(attributeNames[i], value));
} catch (Exception e) {
e.printStackTrace();
}
}
return (resultList);
}
public AttributeList setAttributes(AttributeList attributes) {
if (attributes == null) {
throw new RuntimeOperationsException(new IllegalArgumentException(
"AttributeList attributes cannot be null"),
"Cannot invoke a setter of " + dClassName);
}
AttributeList resultList = new AttributeList();
if (attributes.isEmpty())
return resultList;
for (Iterator i = attributes.iterator(); i.hasNext();) {
Attribute attr = (Attribute) i.next();
try {
setAttribute(attr);
String name = attr.getName();
Object value = getAttribute(name);
resultList.add(new Attribute(name, value));
} catch (Exception e) {
e.printStackTrace();
}
}
return (resultList);
}
/**
* 设置操作
*/
public Object invoke(String operationName, Object params[],
String signature[]) throws MBeanException, ReflectionException {
// 检查方法名是否为空
if (operationName == null) {
throw new RuntimeOperationsException(new IllegalArgumentException(
"Operation name cannot be null"),
"Cannot invoke a null operation in " + dClassName);
}
if (operationName.equals("reset")) {
reset();
return null;
} else {
throw new ReflectionException(new NoSuchMethodException(
operationName), "Cannot find the operation "
+ operationName + " in " + dClassName);
}
}
public MBeanInfo getMBeanInfo() {
return (dMBeanInfo);
}
/*
* ----------------------------------------------------- 下面是公共方法
* -----------------------------------------------------
*/
public String getState() {
return state;
}
public void setState(String s) {
state = s;
nbChanges++;
}
public Integer getNbChanges() {
return new Integer(nbChanges);
}
public void reset() {
state = "initial state";
nbChanges = 0;
nbResets++;
}
public Integer getNbResets() {
return new Integer(nbResets);
}
/**
* 构造辅助信息,这里用了很多辅助类,具体看规范
*/
private void buildDynamicMBeanInfo() {
dAttributes[0] = new MBeanAttributeInfo("State", "java.lang.String",
"State: state string.", true, true, false);
dAttributes[1] = new MBeanAttributeInfo(
"NbChanges",
"java.lang.Integer",
"NbChanges: number of times the State string has been changed.",
true, false, false);
Constructor[] constructors = this.getClass().getConstructors();
dConstructors[0] = new MBeanConstructorInfo(
"SimpleDynamic(): Constructs a SimpleDynamic object",
constructors[0]);
MBeanParameterInfo[] params = null;
dOperations[0] = new MBeanOperationInfo(
"reset",
"reset(): reset State and NbChanges attributes to their initial values",
params, "void", MBeanOperationInfo.ACTION);
dMBeanInfo = new MBeanInfo(dClassName, dDescription, dAttributes,
dConstructors, dOperations, new MBeanNotificationInfo[0]);
}
}
agent代码:
import javax.management.*;
public class SimpleAgent {
private MBeanServer server = null;
ObjectName mbeanObjectName = null;
String mbeanName = "SimpleDynamic";
public SimpleAgent() {
server = MBeanServerFactory.createMBeanServer();
String domain = server.getDefaultDomain();
try {
mbeanObjectName = new ObjectName(domain + ":type=" + mbeanName);
server.createMBean(mbeanName, mbeanObjectName);
} catch (MalformedObjectNameException e) {
e.printStackTrace();
System.out.println("\nEXITING...\n");
System.exit(1);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public String getState() throws AttributeNotFoundException,
InstanceNotFoundException, MBeanException, ReflectionException {
return (String) server.getAttribute(mbeanObjectName, "State");
}
public Integer getNChange() throws AttributeNotFoundException,
InstanceNotFoundException, MBeanException, ReflectionException {
return (Integer) server.getAttribute(mbeanObjectName, "NbChanges");
}
public void printMBeanInfo() {
MBeanInfo info = null;
try {
info = server.getMBeanInfo(mbeanObjectName);
} catch (Exception e) {
System.out.println("\t!!! Could not get MBeanInfo object for "
+ mbeanName + " !!!");
e.printStackTrace();
return;
}
System.out.println("\nCLASSNAME: \t" + info.getClassName());
System.out.println("\nDESCRIPTION: \t" + info.getDescription());
System.out.println("\nATTRIBUTES");
MBeanAttributeInfo[] attrInfo = info.getAttributes();
if (attrInfo.length > 0) {
for (int i = 0; i < attrInfo.length; i++) {
System.out.println(" ** NAME: \t" + attrInfo[i].getName());
System.out.println(" DESCR: \t" + attrInfo[i].getDescription());
System.out.println(" TYPE: \t" + attrInfo[i].getType()
+ "\tREAD: " + attrInfo[i].isReadable() + "\tWRITE: "
+ attrInfo[i].isWritable());
}
} else
System.out.println(" ** No attributes **");
System.out.println("\nCONSTRUCTORS");
MBeanConstructorInfo[] constrInfo = info.getConstructors();
for (int i = 0; i < constrInfo.length; i++) {
System.out.println(" ** NAME: \t" + constrInfo[i].getName());
System.out.println(" DESCR: \t" + constrInfo[i].getDescription());
System.out.println(" PARAM: \t"
+ constrInfo[i].getSignature().length + " parameter(s)");
}
System.out.println("\nOPERATIONS");
MBeanOperationInfo[] opInfo = info.getOperations();
if (opInfo.length > 0) {
for (int i = 0; i < opInfo.length; i++) {
System.out.println(" ** NAME: \t" + opInfo[i].getName());
System.out.println(" DESCR: \t" + opInfo[i].getDescription());
System.out.println(" PARAM: \t"
+ opInfo[i].getSignature().length + " parameter(s)");
}
} else
System.out.println(" ** No operations ** ");
System.out.println("\nNOTIFICATIONS");
MBeanNotificationInfo[] notifInfo = info.getNotifications();
if (notifInfo.length > 0) {
for (int i = 0; i < notifInfo.length; i++) {
System.out.println(" ** NAME: \t" + notifInfo[i].getName());
System.out
.println(" DESCR: \t" + notifInfo[i].getDescription());
}
}
}
public void reset() throws InstanceNotFoundException, MBeanException,
ReflectionException {
server.invoke(mbeanObjectName, "reset", null, null);
}
public void setState(String state) {
Attribute nbChangesAttribute = new Attribute("State", state);
try {
server.setAttribute(mbeanObjectName, nbChangesAttribute);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setNChange(Integer nchange) {
Attribute nbChangesAttribute = new Attribute("NbChanges", nchange);
try {
server.setAttribute(mbeanObjectName, nbChangesAttribute);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SimpleAgent agent = new SimpleAgent();
try {
agent.printMBeanInfo();
System.out.println(agent.getState());
System.out.println(agent.getNChange());
agent.setState("come on, man");
// agent.setNChange(new Integer(6));
System.out.println(agent.getState());
System.out.println(agent.getNChange());
agent.reset();
System.out.println(agent.getState());
System.out.println(agent.getNChange());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
相关推荐
jmx-mbeans 创建了自定义Mbean类,以接收一些简单操作(如求和操作)的度量。 创建了MBeanServer并注册了自定义Mbean类。 使用jconsole工具连接到我的MBeanServer。 在jconsole中,能够查看自定义Mbean属性,...
jmx 实例 rmi mbean,采用rmi方式进行jmx的mbean管理,通过这个实例能够了解jmx的应用
定制保险丝 通用 JMX Mbeans 的 JON Fuse 插件扩展
本课程介绍JMXAPI的基本概念,它被称之为被管理的bean,或者MBean。MBean是一个被管理的Java对象,就像Javabean组件一样,但是它遵从JMX规范的设计模式。MBean可以表示设备、应用或者任何需要被管理的资源。MBeans...
Java分布式应用学习笔记09JMX-MBean的介绍
JMX 1.2.1 Reference Implementation(重点) Include com.sun.jdmk.comm.HtmlAdaptorServer class http://www.sun.com/software/jdmk/ Downloads, sun-jdmk-runtime-5.1-b34.2.zip/SUNWjdmk/5.1/lib/jdmkrt.jar
NULL 博文链接:https://jasonhan-sh-hotmail-com.iteye.com/blog/1171904
通用 JMX MBean 收集器,它使用 Boundary API 创建指标并发布它们。 这个 java 应用程序读取一个配置文件,其名称作为参数传递。 配置文件是一个 JSON 结构,它定义了 JMX 连接、要收集的 MBean 属性以及边界度量...
JMX是指Java管理扩展,通过jmx可以监控java应用服务器的各项性能指标,jvm的性能指标等
Commons-JMX ... ObjectName objectName = MBeans.register(mbean); // Object name is: '<YourMXBean>:type=YourMXBean' 使用自定义名称注册MBean: IYourMXBean mbean = new YourMXBean(); ObjectName
书中提供了几个典型的例子,兼顾各种开发平台,这些例子的代码稍作修改就可以直接应用于项目开发之中,代码源文件可以从图灵网站下载。本书内容广泛且深入,同时适用于各个层次的Web应用开发人员。
jmxutils.zip,导出jmx mbean使导出jmx mbean变得容易
为什么JMX那么受欢迎,JMX到底有那些优势只得人们去学习和理解,本文从JMX的基本架构、hellowold jmx以及spring对JMX的支持讲起,希望大家能通过本文对JMX有个基础的认识,并能通过本文为今后学习JMX打个基础
1.JMX与SPRING 结合实例 2.标准MBean 与非标准MBean 注册 3.基于接口和注解的MBean 注册 4.发布通知,处理通知及配置
Tomcat 8 Extras catalina-jmx-remote.jar,JMX监控所需文件之一。 JMX Remote Lifecycle Listener - org.apache.catalina.mbeans.JmxRemoteLifecycleListener
JMX到Prometheus导出器:一个收集器,该收集器可以可配置地抓取和公开JMX目标的mBean。 该导出程序旨在作为Java代理运行,公开HTTP服务器并提供本地JVM的度量。 它也可以作为独立的HTTP服务器运行,并刮擦远程JMX...
jmx快速上手 jmx快速上手 jmx快速上手 jmx快速上手
jmx转储 在命令行上将JMX指标转储为JSON。 安装 从下载独立的二进制文件或jar。 也可以通过自制水龙头使用 brew tap r4um/homebrew brew install jmx-dump 旧版本。 用法 使用发行版中的独立二进制文件或jar。 $ ...
Fiddler导出jmx文件,解决Fiddler导出文件中 没有jmx文件选项,各个版本fiddler都适用
Description Resource Path Location Type Missing artifact com.sun.jmx:jmxri:jar:1.2.1 pom.xml /eshop-storm line 2 Maven Dependency Problem