我们常见利用jmx来获取监听事件,以此达到数据状态变更的通知。
观测gc
jmx里已经内置了很多mbean,这里展示一下如何发生gc后获取到gc的事件。
我们先写一个事件处理类,这个类表示事件收到后如何处理。
public class GarbageNotificationListener implements NotificationListener {
@Override
public void handleNotification(Notification notification, Object handback) {
String notifType = notification.getType();
if (notifType.equals(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION)) {
CompositeData cd = (CompositeData) notification.getUserData();
GarbageCollectionNotificationInfo info = GarbageCollectionNotificationInfo.from(cd);
System.out.println(info.getGcCause() + info.getGcName());
}
}
}
需要实现NotificationListener,主要实现handleNotification方法。具体的数据在notification里。
这里大家很好奇,为啥知道要强制类型转化为CompositeData。这里需要看java doc,在openjdk里还会有测试代码。上面的代码主要输出了垃圾回收期的名字和gc的原因。
我们开始给对应的mbean增加监听事件。
List garbageCollectorMXBeanList = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMXBeanList) {
NotificationEmitter notificationEmitter = (NotificationEmitter) garbageCollectorMXBean;
NotificationListener listener = new GarbageNotificationListener();
notificationEmitter.addNotificationListener(listener, null, null);
}
普通的mbean没有增加事件的功能。这里就需要做转化,能加监听的mbean都是可以转化为NotificationEmitter。然后我们增加自己的listener。addNotificationListener有三个参数,第一个就是我们的监听器,第二个是过滤器,这个这里不讲。第三个是handback对象。这里传什么,在handleNotification(Notification notification, Object handback)中,handback就会收到什么。这里需要业务逻辑进行串联。
自定义mbean增加监听器
上面只是提到了如何给内置的mbean增加监听器,那么如何给自己定义的mbean也增加这个功能呢。
@MXBean
public interface MyListenerInterface {
void sendInfo();
}
接口和普通的mbean没有区别
public class SenderBean extends NotificationBroadcasterSupport implements MyListenerInterface {
private int seq = 0;
@Override
public void sendInfo() {
Notification notification = new Notification("sender", this, seq++,"doubi");
sendNotification(notification);
}
}
在实现的时候,要继承NotificationBroadcasterSupport。在我们的code里。可以增加Notification,然后sendNotification做通知。这样一个可以被监听注册的mbean就做好了。
开始自己注册,然后增加listener。
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName objectName = new ObjectName("com.xp:name=listener,type=mybeans");
SenderBean bean=new SenderBean();
server.registerMBean(bean, objectName);
bean.addNotificationListener((Notification notification, Object handback)->{
System.out.println( notification.getMessage());
},null,null);
上面的案例就简单的使用了lambda。逻辑比较简单,此时因为bean本身就有方法,所以不用做类型转。
jmx事件的好处
mbean本身就是对系统状态的一种暴露,其实通过不断的轮训查询变化,也可以大体知道数据的变化情况。如果数据变化不频繁的时候,可能呢多次的轮训是一种浪费。这里就需要通过事件机制,等偶尔有变化的时候,再进行数据操作。极大的节省了资源。
事件通知的缺点
目前的事件通知,还没有特别统一的规则定义,会使用object作为传递的对象,但是对象类要如何被使用,这个强烈依赖api文档的使用,需要用文档来知道对方如何调用,强转到哪个类型,如何获取数据,这个有很大的动态特性,完全依赖编码人员的构造。
共同学习,写下你的评论
评论加载中...
作者其他优质文章