/** *Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)] *Licensed under the Apache License, Version 2.0 (the "License"); *you may not use this file except in compliance with the License. *You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 *Unless required by applicable law or agreed to in writing, *software distributed under the License is distributed on an "AS IS" BASIS, *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, *either express or implied. See the License for the specific language governing permissions and limitations under the License */ /** *Copyright [2009-2010] [dennis zhuang(killme2008@gmail.com)] *Licensed under the Apache License, Version 2.0 (the "License"); *you may not use this file except in compliance with the License. *You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 *Unless required by applicable law or agreed to in writing, *software distributed under the License is distributed on an "AS IS" BASIS, *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, *either express or implied. See the License for the specific language governing permissions and limitations under the License */ package net.rubyeye.xmemcached.monitor; import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.remote.JMXConnectorServer; import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Enable JMX supports,default is false: </br> * *   java -Dxmemcached.jmx.enable=true -Dxmemcached.rmi.port=7077 * -Dxmemcached.rmi.name=xmemcachedServer </br> * * Access MBean through: </br> * *   service:jmx:rmi:///jndi/rmi://[host]:7077/xmemcachedServer </br> * * You can add or remove memcached server dynamically and monitor * XmemcachedClient?'s behavior through MBeans.Other options: </br> * <ul> * <li>-Dxmemcached.rmi.port</li> * <li>-Dxmemcached.rmi.name</li> * </ul> * * @author dennis * */ public final class XMemcachedMbeanServer { private static final Logger log = LoggerFactory .getLogger(XMemcachedMbeanServer.class); private MBeanServer mbserver = null; private static XMemcachedMbeanServer instance = new XMemcachedMbeanServer(); private JMXConnectorServer connectorServer; private Thread shutdownHookThread; private volatile boolean isHutdownHookCalled = false; private XMemcachedMbeanServer() { initialize(); } private void initialize() { if (mbserver != null && connectorServer != null && connectorServer.isActive()) { return; } // 鍒涘缓MBServer String hostName = null; try { InetAddress addr = InetAddress.getLocalHost(); hostName = addr.getHostName(); } catch (IOException e) { log.error("Get HostName Error", e); hostName = "localhost"; } String host = System.getProperty("hostName", hostName); try { boolean enableJMX = Boolean.parseBoolean(System.getProperty( Constants.XMEMCACHED_JMX_ENABLE, "false")); if (enableJMX) { mbserver = ManagementFactory.getPlatformMBeanServer(); int port = Integer.parseInt(System.getProperty( Constants.XMEMCACHED_RMI_PORT, "7077")); String rmiName = System.getProperty( Constants.XMEMCACHED_RMI_NAME, "xmemcachedServer"); Registry registry = null; try { registry = LocateRegistry.getRegistry(port); registry.list(); } catch (Exception e) { registry = null; } if (null == registry) { registry = LocateRegistry.createRegistry(port); } registry.list(); String serverURL = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/" + rmiName; JMXServiceURL url = new JMXServiceURL(serverURL); connectorServer = JMXConnectorServerFactory .newJMXConnectorServer(url, null, mbserver); connectorServer.start(); shutdownHookThread = new Thread() { @Override public void run() { try { isHutdownHookCalled = true; if (connectorServer .isActive()) { connectorServer .stop(); log.warn("JMXConnector stop"); } } catch (IOException e) { log.error("Shutdown Xmemcached MBean server error", e); } } }; Runtime.getRuntime().addShutdownHook(shutdownHookThread); log.warn("jmx url: " + serverURL); } } catch (Exception e) { log.error("create MBServer error", e); } } public static XMemcachedMbeanServer getInstance() { return instance; } public final void shutdown() { try { if (connectorServer != null && connectorServer.isActive()) { connectorServer.stop(); log.warn("JMXConnector stop"); if (!isHutdownHookCalled) { Runtime.getRuntime().removeShutdownHook(shutdownHookThread); } } } catch (IOException e) { log.error("Shutdown Xmemcached MBean server error", e); } } public boolean isRegistered(String name) { try { return mbserver != null && mbserver.isRegistered(new ObjectName(name)); } catch (Exception e) { throw new RuntimeException(e); } } public boolean isActive() { return mbserver != null && connectorServer != null && connectorServer.isActive(); } public int getMBeanCount() { if (mbserver != null) { return mbserver.getMBeanCount(); } else { return 0; } } public void registMBean(Object o, String name) { if (isRegistered(name)) { return; } // 娉ㄥ唽MBean if (mbserver != null) { try { mbserver.registerMBean(o, new ObjectName(name)); } catch (Exception e) { throw new RuntimeException(e); } } } }