JMX - addConnectionNotificationListener没有处理连接关闭

时间:2014-03-10 09:35:39

标签: jmx

我正在尝试使用JMX连接检测远程服务器的关闭。

我正在使用的方法是

  • 创建与Weblogic Server的JMX连接,
  • 将“addConnectionNotificationListener”添加到连接器

现在如果服务器出现故障,我希望收到类型为“JMXConnectionNotification”的通知。

这不会发生。为了确定连接不再有效,我必须访问它(通过任何小的方法),并且当访问连接对象时,只有我的通知监听器获得通知。如果这样做,那就不是实时的了。

有人能指出我可以做些什么来解决这个问题吗?


我的代码供参考 -

public class PrintServerState {

   private static MBeanServerConnection connection;
   private static JMXConnector connector;
   private static final ObjectName service;
   private JMXConnectorNotificationListener connectionListener = null;

   static {
      try {
        service = 
         new ObjectName(
            "com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean");
      } catch (MalformedObjectNameException e) {
         throw new AssertionError(e.getMessage());
      }
   }

   public void initConnection
      (String hostname, String portString, 
          String username, String password) throws IOException,
      MalformedURLException
   { 
      String protocol = "t3";
      Integer portInteger = Integer.valueOf(portString);
      int port = portInteger.intValue();

      String jndiroot = "/jndi/";
      String mserver = "weblogic.management.mbeanservers.domainruntime";
      //String mserver = "weblogic.management.mbeanservers.runtime";
      JMXServiceURL serviceURL = new JMXServiceURL(protocol, hostname,
         port, jndiroot + mserver);
      Hashtable h = new Hashtable();
      h.put(Context.SECURITY_PRINCIPAL, username);
      h.put(Context.SECURITY_CREDENTIALS, password);
      h.put(JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES,
         "weblogic.management.remote");
      System.out.println(serviceURL);
      connector = JMXConnectorFactory.connect(serviceURL,h);
       if (connector != null)
       {
           connectionListener = new JMXConnectorNotificationListener();
           System.out.println("Created one listener for connector ");
       }
       /* try{
            connector.addConnectionNotificationListener(connectionListener,null,null);
       }catch(Exception e){
           System.out.println("Connector does not support notfication Listener");
       } */
      connection = connector.getMBeanServerConnection();
   }

   public static void main(String[] args) throws Exception {

      String hostname = "example.domain.com";
      String portString = "7001";
      String username = "weblogic";
      String password = "password";

      PrintServerState s = new PrintServerState();

      s.initConnection(hostname, portString, username, password);
      String test = connection.getDefaultDomain();
        System.out.println(test); 

      for(int i =0 ; i<=20;i++){
          Thread.sleep(1000);
          System.out.println(i);
      }

      String test1 = connection.getDefaultDomain();
        System.out.println(test1); 
   }


   //INNER CLASS
   private class JMXConnectorNotificationListener implements NotificationListener{
        public JMXConnectorNotificationListener() {
            connector.addConnectionNotificationListener(this,null,null);

        }

        public void handleNotification(Notification notification,
                                       Object handback) {
            System.out.println("Notification");
            String type = notification.getType();
            if (JMXConnectionNotification.CLOSED.equals(type) ||
                JMXConnectionNotification.FAILED.equals(type))
            {
               System.out.println("JMX Connection failed!!!");
            } else if (JMXConnectionNotification.OPENED.equals(type)) {
                System.out.println("JMX Connection OPENED!!!");
            } else {
               System.out.println("Recvd JMXConnectionNotification status as " + type);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

由于底层实施的性质,一旦连接断开,您就无法收到通知。想想客户端套接字 - 了解服务器何时关闭它的唯一方法是尝试从套接字读取并看到-1或获得IOException。

您有两种选择:

  1. 保持原样并在尝试访问bean /连接时获得通知,然后在现场重新连接。

  2. 定期尝试访问连接(可能只是尝试读取jvm运行时属性或不会产生负担的事情)与计划执行程序,以便您尽快收到通知。

  3. 使用哪个:

    如果某些预定服务在后台通过JMX轮询数据,则选项1就足够了。

    如果根据用户请求执行操作,则可能首选选项2,以便您可以在用户注意到之前尝试重新连接。