• jmx完整示例


    很早就开始去了解这个了,不过一直都是皮毛,基本概念明白,具体api几乎一无不知。。。

    认真看了几篇文章,做了测试,终于有所了解

    参考 入门级别: http://www.cnblogs.com/agou/articles/286871.html http://www.cnblogs.com/allenny/articles/179208.html

    写得最好的:http://www.cnblogs.com/yaohonv/archive/2012/02/08/jmx.html, 图也很清楚,不过初入门的时候看起来比较吃力, 其中对jmx-rmi有所涉及,不错,可惜实验不通。没地方下载jmxremoting.jar

    这个相当不错:http://www.cnblogs.com/zjstar12/archive/2012/06/10/2544387.html

    http://www.cnblogs.com/xzh31390080/articles/2231213.html 很精辟简练,不过只能是最后才可以看,初学者看了也白看。。 像我之前那样怎么看都没用。

    个人理解:

    关于mbean:

    standard MBean,这种类型的MBean最简单: 一个接口,一个实现类即可,不需要任何其他类依赖,但是命名必须遵循一定的规范,例如我们的MBean为Hello,则接口必须为HelloMBean。

    假如某个属性只有get方法,则说明这个属性是只读的,get/set都有的话,说明这个属性是可读可写的

    DynamicMBean 可以动态拓展需要管控的资源,即允许bean里面的属性、方法可变,因此需要实现额外的方法:

    http://www.cnblogs.com/zjstar12/archive/2012/06/10/2544387.html

    package javax.management; public interface DynamicMBean{     public Object getAttribute( String attribute )throws AttributeNotFoundException, MBeanException,ReflectionException;

        public void setAttribute( Attribute attribute )throws AttributeNotFoundException,InvalidAttributeValueException,MBeanException,ReflectionException;

        public AttributeList getAttributes( String[] attributes );

        public AttributeList setAttributes( AttributeList attributes );

        public Object invoke( String actionName, Object[] params,String[] signature ) throws MBeanException,ReflectionExceptionn

        public MBeanInfo getMBeanInfo(); }

    openMBean及其他一些未规范的就不说了

    关于jmx客户端都jmx服务端的访问:

    1 通过浏览器,jmx client程序启用http协议,这个时候需要一个HTMLAdapter

    2 jconsole。  不能访问? 看看: http://www.cnblogs.com/orientsun/archive/2012/07/25/2608525.html

    3 程序访问?

    a 通过JMXConnector

    http://www.cnblogs.com/yaohonv/archive/2012/02/08/jmx.html

    b 通过http协议,HTMLAdapter?

    一些重要的接口:

    ManagementFactory 专门生产MBeanServer 

    MBeanServer  一般就是MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();

    这个很重要,主要就是通过它来管理mbean的,主要方法有:registerMBean,unRegisterMBean,addNotificationListenerremoveNotificationListener

     createMBean/queryMBean

    get/setAttributes

    instantiate 不知道干什么的。。。

       

    JMXServiceURL 创建ConnectorServer需要用到,

     RMIConnectorServer  -> ConnectorServer

    JMXConnector

    待续。。

    =========================================== 20140215 =========================================================

    今天终于搞定!!

    一个完整的例子贴上!!!:

    package jmx;
    public interface HelloMBean {
        // management attributes
        public String getName();
        public void setName(String name);
        // management operations
        public void print();
    }
    package jmx;
    public class Hello implements HelloMBean {
    
        private String name = "";
    
        public String getName() {
        return name;
        }
    
        public void setName(String name) {
        this.name = name;
        }
    
        public void print() {
        System.out.println("Hello, " + name + "!!" );
        }
    }
    package jmx;
    
    import java.lang.management.ManagementFactory;
    import java.net.InetAddress;
    import java.rmi.registry.LocateRegistry;
    import java.rmi.server.RMISocketFactory;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.atomic.AtomicBoolean;
    
    import javax.management.MBeanServer;
    import javax.management.ObjectName;
    import javax.management.remote.JMXAuthenticator;
    import javax.management.remote.JMXConnectorServer;
    import javax.management.remote.JMXConnectorServerFactory;
    import javax.management.remote.JMXPrincipal;
    import javax.management.remote.JMXServiceURL;
    import javax.management.remote.rmi.RMIConnectorServer;
    import javax.security.auth.Subject;
    
    public class JmxServer {
    
        private final AtomicBoolean runningFlag = new AtomicBoolean(true);
        
        /**
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            try {
                MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    
                String addr = "10.74.169.50:31999";//本机的话ip地址可以使用localhost或者127.0.0.1
                JMXServiceURL address = new JMXServiceURL("service:jmx:rmi://"
                        + addr + "/jndi/rmi://" + addr + "/jmxrmi");
    
                Map<String, Object> jmxEnvironment = new HashMap<String, Object>();
                jmxEnvironment.put("jmx.remote.credentials", new String[] { "saf",
                        "asswrd" });
    
                InetAddress ipInterface = InetAddress.getByName("10.74.169.50");
                RMISocketFactory rmiFactory = RMISocketFactory.getDefaultSocketFactory();
                        //new AnchorSocketFactory(ipInterface,"false");
                LocateRegistry.createRegistry(31999, null, rmiFactory);
                
                 // 這個是必須的,否則報 no such object in table之類是異常!!!! 花了相當長時間才發現這點
                jmxEnvironment.put(
                        RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
                        rmiFactory);
    
                // 需要认证则这么写:
    //            JMXAuthenticator auth = createJMXAuthenticator();
    //            jmxEnvironment.put(JMXConnectorServer.AUTHENTICATOR, auth);
    
                JMXConnectorServer connector = JMXConnectorServerFactory
                        .newJMXConnectorServer(address, jmxEnvironment,
                                ManagementFactory.getPlatformMBeanServer());
                HelloMBean mbean = new Hello();
                ObjectName testMBeanName = new ObjectName(
                        "helloMBean:name=helloMBean");
                testMBeanName = new ObjectName("helloMBeanDomain", "type",
                        "HelloMBean");
                mbs.registerMBean(mbean, testMBeanName);
    
                connector.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    //        try {//这个好像没用
    //            synchronized (this) {
    //                while (runningFlag.get()) {
    //                    this.wait();
    //                }
    //            }
    //        } catch (Exception e) {
    //
    //        }
        }
    
        private JMXAuthenticator createJMXAuthenticator() {
            return new JMXAuthenticator() {
                public Subject authenticate(Object credentials) {
                    String[] sCredentials = (String[]) credentials;
                    if (null == sCredentials || sCredentials.length != 2) {
                        throw new SecurityException("Authentication failed!");
                    }
                    String userName = sCredentials[0];
                    String pValue = sCredentials[1];
                    if ("saf".equals(userName) && "asswrd".equals(pValue)) {
                        Set principals = new HashSet();
                        principals.add(new JMXPrincipal(userName));
                        return new Subject(true, principals, Collections.EMPTY_SET,
                                Collections.EMPTY_SET);
                    }
                    throw new SecurityException("Authentication failed!");
                }
            };
        }
    
    }
    package jmx;
    
    import java.lang.management.ManagementFactory;
    import java.lang.management.ThreadMXBean;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.management.JMX;
    import javax.management.MBeanServerConnection;
    import javax.management.ObjectName;
    import javax.management.remote.JMXConnector;
    import javax.management.remote.JMXConnectorFactory;
    import javax.management.remote.JMXServiceURL;
    
    public class JmxClient {
    
        /**
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException {
            ObjectName hello_name = null;
            try {
                hello_name = new ObjectName("helloMBeanDomain", "type",
                        "HelloMBean");
                System.out.println("	OBJECT NAME = " + hello_name);
                // service:jmx:rmi://%s:%d/jndi/rmi://%s:%d/jmxrmi
                String addr = "10.74.169.50:31999";
                JMXServiceURL address = new JMXServiceURL("service:jmx:rmi://"
                        + addr + "/jndi/rmi://" + addr + "/jmxrmi");
                System.out.println("JmxRemote.main()1");
                Map<String, Object> jmxEnvironment = new HashMap<String, Object>();
    
                // 如果服務端有认证,則客戶端也要这么写:
                // jmxEnvironment.put("jmx.remote.credentials", new String[] {
                // "saf", "asswrd"});
    
                JMXConnector connector = JMXConnectorFactory.connect(address,
                        jmxEnvironment);
                System.out.println("JmxRemote.main()2");
                MBeanServerConnection mbs = connector.getMBeanServerConnection();
                System.out.println("JmxRemote.main()3");
                ThreadMXBean threadBean = ManagementFactory.newPlatformMXBeanProxy(
                        mbs, ManagementFactory.THREAD_MXBEAN_NAME,
                        ThreadMXBean.class);
                System.out
                        .println(" getThreadCount " + threadBean.getThreadCount());// 线程数量
    
                MBeanServerConnection connection = connector
                        .getMBeanServerConnection();
                HelloMBean helloMBean = JMX.newMXBeanProxy(connection, hello_name,
                        HelloMBean.class);
    
                System.out.println("aaaaaaaa " + helloMBean);
    
                helloMBean.setName("LKKKKKKK ddd basdf");
    
                helloMBean.print();
    
           connector.close();

    }
    catch (Exception e) { e.printStackTrace(); return; } } }
    package jmx;
    
    import java.io.IOException;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.rmi.server.RMISocketFactory;
    
    import javax.net.ssl.SSLServerSocket;
    import javax.net.ssl.SSLServerSocketFactory;
    import javax.net.ssl.SSLSocketFactory;
    
    public class AnchorSocketFactory extends RMISocketFactory {
        private InetAddress ipInterface = null;
        private String sslEnabled;
        
        public AnchorSocketFactory() {
        }
    
        public AnchorSocketFactory(InetAddress ipInterface, String sslEnabled) {
            this.ipInterface = ipInterface;
            this.sslEnabled = sslEnabled;
        }
    
        public ServerSocket createServerSocket(int port) throws IOException {
            if (this.sslEnabled.equalsIgnoreCase("true")) {
                SSLServerSocket sslserversocket = null;
                try {
                    SSLServerSocketFactory sslserversocketfactory =
                        (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
                    sslserversocket =
                        (SSLServerSocket)sslserversocketfactory.createServerSocket(port,
                                50,
                                this.ipInterface);
                } catch (IOException e) {
                    throw e;
                }
                return sslserversocket;
            } else {
                ServerSocket serverSocket = null;
                try {
                    serverSocket = new ServerSocket(port, 50, ipInterface);
                } catch (IOException e) {
    
                    throw e;
                }
    
                return serverSocket;
            }
        }
    
        public Socket createSocket(String dummy, int port) throws IOException {
            if (this.sslEnabled.equalsIgnoreCase("true")) {
                return SSLSocketFactory.getDefault()
                        .createSocket(this.ipInterface.getHostName(), port);
            } else {
                return new Socket(ipInterface, port);
            }
        }
    }

    如果是通过jconsole连接的就这么来:

    NOTE1:

    server端步骤:

    1 创建MBeanServerFactory mbs = ManagementFactory.getPlatformMBeanServer();

      或者MBeanServerFactory mbs = MBeanServerFactory.createMBeanServer("HelloAgentaa"); //  这个域名要和下面的保持一致

    2 设置jmxEnvMap,必须的有RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,可选的有账号密码、ssl参数等

    3 创建JMXServiceURL,支持多种协议,http/snmp/rmi 等,有一定的格式,rmi的格式是:service:jmx:rmi://%s:%d/jndi/rmi://%s:%d/jmxrmi

    4 获取JMXConnectorServer connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, jmxEnvMap, mbs);

    5 创建ObjectName helloWorldName = new ObjectName("HelloAgentaa:type=hwa");

    6 注册MBean  mbs.registerMBean(hw, helloWorldName);

    7 启动connectorServer   connectorServer.start();

     client端步骤:

    1 同上2  如server端有设置账号密码、ssl参数等,client端需要一致

    2 同上3

    3 获取JMXConnector connector = JMXConnectorFactory.connect(address, jmxEnvironment);  需要注意的是,这里我们使用的是JMXConnector,而非JMXConnectorServer!

    4 创建MBeanServerConnection connection = connector.getMBeanServerConnection();

      这里很关键的是,我们需要一个MBeanServerConnection, 而不再是JMXConnectorServer! 因为这个client端。。

    5 同上5

    6 获取MBean: HelloWorldMBean helloMBean = JMX.newMXBeanProxy(connection, hello_name, HelloWorldMBean.class);

      这里很关键的是,newMXBeanProxy的第三个参数和返回结果都是MBean接口,否则报错

    7 尽情使用MBean,嘎嘎嘎!

    8 使用后关闭MBeanServerConnection

    NOTE2

    ObjectName有三种构造函数:
      helloWorldName = new ObjectName("HelloAgentaa", "type", "hwa");
       helloWorldName = new ObjectName("HelloAgentaa:type=hwa");
       Hashtable<String, String> sadf = new Hashtable<String, String>(); sadf.put("type", "hwa");helloWorldName = new ObjectName("HelloAgentaa",sadf );

    上面三种形式等价,但是不能,helloWorldName = new ObjectName("HelloAgentaa:type=hwa", key, value); 或者new ObjectName("HelloAgentaa:type=hwa", map); 这样混合使用!

    NOTE3

    创建MBeanServerFactory有两种方式:

    1 MBeanServerFactorymbs = ManagementFactory.getPlatformMBeanServer(); //  获取jmx平台基础已有的MBeanServerFactory

    2 或者MBeanServerFactory mbs = MBeanServerFactory.createMBeanServer("HelloAgentaa"); // 获取新的MBeanServerFactory

    具体使用哪种要酌情考虑

    (clien不t需要MBeanServerFactory)

    NOTE4

    客户端使用完记得关闭JMXConnector

    我这里没有设置jmx账号,所以下面两栏为空

    如果需要使用ssl通道加密数据的话,则需执行(当然,要jmx服务器配置好ssl先):

    jconsole -J-Djavax.net.ssl.trustStore=D:jmxcertificateserverTrustStore -J-Djavax.net.ssl.trustStorePassword=asswor

    然后再在弹出的jconsole页面——远程连接——输入ip/port/username/password。。。。。

  • 相关阅读:
    nginx预防常见攻击
    nginx性能优化(针对于高并发量仅供参考,并不是方案)
    nginx平滑升级(1.14--1.15)
    LAMP动静分离安装(源码安装)
    洛谷-P1098 字符串的展开
    洛谷-P1086 花生采摘
    洛谷-P1042 乒乓球
    洛谷-P1031 均分纸牌
    洛谷-P1023 税收与补贴问题
    洛谷-P1125 笨小猴
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/jmx.html
Copyright © 2020-2023  润新知