手记

利用jmx达到事件响应

我们常见利用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文档的使用,需要用文档来知道对方如何调用,强转到哪个类型,如何获取数据,这个有很大的动态特性,完全依赖编码人员的构造。

0人推荐
随时随地看视频
慕课网APP