JMX
JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展。这种机制可以方便的管理、监控正在运行中的Java程序。常用于管理线程,内存,日志Level,服务重启,系统环境等。The JMX technology provides a simple, standard way of managing resources such as applications, devices, and services. Because the JMX technology is dynamic, you can use it to monitor and manage resources as they are created, installed and implemented. You can also use the JMX technology to monitor and manage the Java Virtual Machine (Java VM).Using the JMX technology, a given resource is instrumented by one or more Java objects known as Managed Beans, or MBeans. These MBeans are registered in a core-managed object server, known as an MBean server. The MBean server acts as a management agent and can run on most devices that have been enabled for the Java programming language.
JMX connectors
The JMX technology defines standard connectors (known as JMX connectors) that enable you to access JMX agents from remote management applications. JMX connectors using different protocols provide the same management interface. Consequently, a management application can manage resources transparently, regardless of the communication protocol used.
JMX Agent
Agent只是一个Java进程,它包括这个MBeanServer和一系列附加的MbeanService。当然这些Service也是通过MBean的形式来发布。JMX Agent是Mbean的
MBean
MBean简介
MBean:是Managed Bean的简称,可以翻译为“管理构件”。在JMX中MBean代表一个被管理的资源实例,通过MBean中暴露的方法和属性,外界可以获取被管理的资源的状态和操纵MBean的行为。事实上,MBean就是一个Java Object,同JavaBean模型一样,外界使用自醒和反射来获取Object的值和调用Object的方法,只是MBean更为复杂和高级一些。MBean通过公共方法以及遵从特定的设计模式封装了属性和操作,以便暴露给管理应用程序。例如,一个只读属性在管理构件中只有Get方法,既有Get又有Set方法表示是一个可读写的属性。一共有四种类型的MBean: Standard MBean, Dynamic MBean, Open MBean, Model MBean。
MBean说明
标准MBean官方定义:A standard MBean is defined by writing a Java interface called SomethingMBean and a Java class called Something that implements that interface. Every method in the interface defines either an attribute or an operation in the MBean. By default, every method defines an operation. Attributes and operations are methods that follow certain design patterns. A standard MBean is composed of an MBean interface and a class. The MBean interface lists the methods for all exposed attributes and operations. The class implements this interface and provides the functionality of the instrumented resource.大致的意思是:标准的MBean是通过定义接口SomethingMBean 和对应接口的实现类Something(注意这两个对应的要一致),在SomethingMBean接口中定义的方法要不是定义属性(对应属性的get/set方法)要不定义是操作,具体如下面代码所示:
public interface HelloMBean {
// getName和setName方法表示的属性Name
public String getName();
public void setName(String name);
public void printHello();
public void printHello(String whoName);
}
public class Hello implements HelloMBean {
private String name; // name属性
@Override
public String getName() {
return name;
}
@Override
public void setName(String name) {
this.name = name;
}
@Override
public void printHello() {
System.out.println("Hello world, "+ name);
}
@Override
public void printHello(String whoName) {
System.out.println("Hello, "+whoName);
}
}
对应的结果如下图所示:
注意:MBean对应的属性是能够读取而且可能允许写入的( an MBean interface consists of named and typed attributes that are readable and possibly writable),如下面代码所示:
public interface HelloMBean {
public void sayHello();
public int add(int x, int y);
// 属性name只允许读取,不允许写入
public String getName();
// 属性cacheSize既可以读取也可以写入
public int getCacheSize();
public void setCacheSize(int size);
}
MBean Notification
To generate notifications, an MBean must implement the interface NotificationEmitter
or extend NotificationBroadcasterSupport
. To send a notification, you need to construct an instance of the classjavax.management.Notification
or a subclass (such as AttributeChangedNotification
), and pass the instance to NotificationBroadcasterSupport.sendNotification
例子代码:
// 扩展类NotificationBroadcasterSupport
public class Hello extends NotificationBroadcasterSupport implements HelloMBean {
private int cacheSize = DEFAULT_CACHE_SIZE;
private static final int DEFAULT_CACHE_SIZE = 200;
private long sequenceNumber = 1;
public int getCacheSize() {
return this.cacheSize;
}
public synchronized void setCacheSize(int size) {
int oldSize = this.cacheSize;
this.cacheSize = size;
System.out.println("Cache size now " + this.cacheSize);
// 定义Notification对象
Notification n = new AttributeChangeNotification(this,
sequenceNumber++, System.currentTimeMillis(),
"CacheSize changed", "CacheSize", "int",
oldSize, this.cacheSize);
sendNotification(n); // 发送
}
@Override
public MBeanNotificationInfo[] getNotificationInfo() {
String[] types = new String[]{
AttributeChangeNotification.ATTRIBUTE_CHANGE
};
System.out.println("=========================");
String name = AttributeChangeNotification.class.getName();
String description = "An attribute of this MBean has changed";
MBeanNotificationInfo info =
new MBeanNotificationInfo(types, name, description);
return new MBeanNotificationInfo[]{info};
}
}
// 监听处理器
public class HelloListener implements NotificationListener {
public void handleNotification(Notification n, Object handback) {
System.out.println("type=" + n.getType());
System.out.println("source=" + n.getSource());
System.out.println("seq=" + n.getSequenceNumber());
System.out.println("send time=" + n.getTimeStamp());
System.out.println("message=" + n.getMessage());
if (n instanceof AttributeChangeNotification){
AttributeChangeNotification attributeChangeNotification = (AttributeChangeNotification)n;
System.out.println("old value="+attributeChangeNotification.getOldValue());
System.out.println("new value="+attributeChangeNotification.getNewValue());
}
if (handback != null) {
if (handback instanceof Hello) {
Hello hello = (Hello) handback;
hello.printHello(n.getMessage());
}
}
}
}
// 关联实体与监控器
public class HelloAgent {
public static void main (String[]args) throws MalformedObjectNameException,
NotCompliantMBeanException, InstanceAlreadyExistsException,
MBeanRegistrationException, IOException {
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
String domainName = "MyMBean";
ObjectName helloName = new ObjectName(domainName + ":name=HelloWorld");
Hello hello = new Hello();
mbs.registerMBean(hello, helloName);
// 管理实体与监听器
hello.addNotificationListener(new HelloListener(),null,hello);
}
}
在Jconsole中对应的结果如下图所示:
TimeStamp | 类型 | UserData | SeqNum | 消息 | 事件 | 源 |
---|---|---|---|---|---|---|
16:56:15:525 | jmx.attribute. change | 4 | CacheSize changed | javax.management. AttributeChangeNotification [source=MyMBean:name=HelloWorld] [type=jmx.attribute.change][message=CacheSize changed] | MyMBean:name =HelloWorld |
Remote management
A JMX connector consists of a connector client and a connector server. A connector server is attached to an MBean server and listens for connection requests from clients. A connector client is responsible for establishing a connection with the connector server. A connector client is usually in a different Java Virtual Machine (Java VM) from the connector server and is often running on a different machine. The JMX API defines a standard connection protocol based on Remote Method Invocation (RMI). This protocol enables you to connect a JMX client to an MBean in an MBean server from a remote location and perform operations on the MBean, exactly as if the operations were being performed locally.
源码地址
例子源码地址:https://github.com/lwjaiyjk/firstMBeanPrj
参考
- https://blog.csdn.net/u013256816/article/details/52800742
- https://docs.oracle.com/javase/tutorial/jmx/mbeans/standard.html
- https://docs.oracle.com/javase/8/docs/technotes/guides/jmx/overview/JMXoverviewTOC.html
- https://docs.oracle.com/javase/8/docs/technotes/guides/jmx/tutorial/tutorialTOC.html