zoukankan      html  css  js  c++  java
  • java-jmx使用

    先粘一段内容

    1、程序初哥一般是写死在程序中,到要改变的时候就去修改代码,然后重新编译发布。
    
    2、程序熟手则配置在文件中(JAVA一般都是properties文件),到要改变的时候只要修改配置文件,但还是必须重启系统,以便读取配置文件里最新的值。
    
    3、程序好手则会写一段代码,把配置值缓存起来,系统在获取的时候,先看看配置文件有没有改动,如有改动则重新从配置里读取,否则从缓存里读取。
    
    4、程序高手则懂得物为我所用,用JMX把需要配置的属性集中在一个类中,然后写一个MBean,再进行相关配置。另外JMX还提供了一个工具页,以方便我们对参数值进行修改。

     JMX的全称为Java Management Extensions. 顾名思义,是管理Java的一种扩展。这种机制可以方便的管理正在运行中的Java程序。常用于管理线程,内存,日志Level,服务重启,系统环境等。

    jmx整体架构: 

    1, Mbean准备

     1, 先建立需要连接的接口

    package com.wenbronk.le.iris.jmx;
    
    /**
     * 实现接口, 可在jconsoler中调用属性
     */
    public interface HelloMBean {
    
        public String getName();
    
        public void setName(String name);
    
        public String getAge();
    
        public void setAge(String age);
    
        public void helloWorld();
    
        public void helloWorld(String str);
    
        public void getTelephone();
    
    }

    2, 实体类继承

    package com.wenbronk.le.iris.jmx;
    
    
    import ch.qos.logback.core.joran.spi.NoAutoStart;
    import lombok.AllArgsConstructor;
    import lombok.NoArgsConstructor;
    
    /**
     * 必须实现 Mbean, 才可以进行注册
     */
    @NoArgsConstructor
    @AllArgsConstructor
    public class Hello implements HelloMBean {
    
        private String name;
        private String age;
    
        @Override
        public String getName() {
            System.out.println("get name::" + name);
            return name;
        }
        @Override
        public void setName(String name) {
            this.name = name;
            System.out.println("set name  " + name);
        }
        @Override
        public String getAge() {
            System.out.println("get age::" + age);
            return age;
        }
        @Override
        public void setAge(String age) {
            this.age = age;
            System.out.println("set age  " + age);
        }
        @Override
        public void helloWorld() {
            System.out.println("hello world");
        }
        @Override
        public void helloWorld(String str) {
            System.out.println("hello world " + str);
        }
        @Override
        public void getTelephone() {
            System.out.println("get telephone");
        }
    }

    2, 使用java命令行指定

    3, 

    package com.wenbronk.le.iris.jmx.local;
    
    import com.wenbronk.le.iris.jmx.Hello;
    import org.junit.Test;
    
    import javax.management.*;
    import java.lang.management.ManagementFactory;
    
    public class HelloAgent {
    
        public static void main(String[] args) throws MalformedObjectNameException, NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException, InterruptedException {
    
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    
            Hello hello = new Hello();
            // com.le.iris:type=ZhixinSource/QPS  域名:name=MBean名称
            ObjectName helloName  = new ObjectName("com.wenbronk.le.jmxBean:name=" + hello.getClass().getName());
    
            ObjectInstance objectInstance = server.registerMBean(hello, helloName);
    
            Thread.sleep(60*1000*1000);
        }
    }

    需要添加password等, 并指定权限

    jmx.access

    monitor readonly
    admin readwrite

    jmx.password

    monitor com.le.big
    admin com.le.big

    启动参数指定: 

    JMX_PORT=12345
    
    JAVA_OPTS="-server 
     -Dcom.sun.management.jmxremote
     -Dcom.sun.management.jmxremote.authenticate=true
     -Dcom.sun.management.jmxremote.password.file=jmx.password
     -Dcom.sun.management.jmxremote.access.file=jmx.access
     -Dcom.sun.management.jmxremote.ssl=false
     -Dcom.sun.management.jmxremote.port=${JMX_PORT}
     -Dcom.sun.management.jmxremote.local.only=false
     -Djava.rmi.server.hostname=${IP}
     -Diris.hostname=${IP}
     -Xmx${MEM}m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:ParallelGCThreads=4
     "
    
    nohup java ${JAVA_OPTS} -jar ${APP_JAR_NAME} ${params} 1>>${APP_HOME}/nohup.log 2>&1 &

    2, 使用java指定远程连接方式: 

    3, agentserver的编写

    package com.wenbronk.le.iris.jmx.remote;
    
    import com.wenbronk.le.iris.jmx.Hello;
    import com.wenbronk.le.iris.jmx.Testtt;
    
    import javax.management.MBeanServer;
    import javax.management.ObjectInstance;
    import javax.management.ObjectName;
    import javax.management.remote.JMXConnectorServer;
    import javax.management.remote.JMXConnectorServerFactory;
    import javax.management.remote.JMXServiceURL;
    import java.io.IOException;
    import java.lang.management.ManagementFactory;
    import java.net.MalformedURLException;
    import java.rmi.RemoteException;
    import java.rmi.registry.LocateRegistry;
    import java.rmi.registry.Registry;
    
    /**
     * 开启后, 可通过jconsoler进行连接
     */
    public class HelloAgentRemote {
    
        public static void main(String[] args) throws Exception {
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
    
            Hello hello = new Hello("vini", "23");
        // 试了下, name 和 type没啥区别 ObjectName helloName
    = new ObjectName("com.wenbronk.le.jmxBean:name=" + hello.getClass().getSimpleName()); //ObjectName helloName1 = new ObjectName("com.wenbronk.le.jmxBean:type=" + hello.getClass().getSimpleName()); Testtt testtt = new Testtt(); ObjectName testtName = new ObjectName("com.wenbronk.le.jmxBean:type=" + testtt.getClass().getSimpleName()); //ObjectName testtName1 = new ObjectName("com.wenbronk.le.jmxBean:name=" + testtt.getClass().getSimpleName()); System.out.println(hello.getClass().getSimpleName()); ObjectInstance instance = mbs.registerMBean(hello, helloName); //ObjectInstance instance3 = mbs.registerMBean(hello, helloName1); ObjectInstance instance2 = mbs.registerMBean(testtt, testtName); //ObjectInstance instance4 = mbs.registerMBean(testtt, testtName1); try { // 注册一个端口并绑定 Registry registry = LocateRegistry.createRegistry(9999); JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi"); //service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi JMXConnectorServer jmxConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, mbs); jmxConnectorServer.start(); }catch (Exception e) { e.printStackTrace(); } } }

    此时可以通过jconsoler工具进行连接了, 

     

    4, 或者自己实现客户端进行连接

    package com.wenbronk.le.iris.jmx.remote;
    
    import com.wenbronk.le.iris.jmx.HelloMBean;
    
    import javax.management.*;
    import javax.management.remote.JMXConnector;
    import javax.management.remote.JMXConnectorFactory;
    import javax.management.remote.JMXConnectorServerFactory;
    import javax.management.remote.JMXServiceURL;
    import java.io.IOException;
    import java.net.MalformedURLException;
    
    /**
     * 远程连接jmx
     */
    public class Client {
    
        public static void main(String[] args) throws Exception {
            JMXServiceURL jmxServiceURL = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
            JMXConnector connect = JMXConnectorFactory.connect(jmxServiceURL, null);
    
            MBeanServerConnection mBeanServerConnection = connect.getMBeanServerConnection();
    
            String[] domains = mBeanServerConnection.getDomains();
            for (int i = 0; i < domains.length; i++) {
                String obj = domains[i];
                System.out.printf("domian[%d] = %s", i, domains[i].toString());
                System.out.println();
            }
    
            // 注册名和之前server的一致
            ObjectName objectName = new ObjectName("com.wenbronk.le.jmxBean:name=Hello");
            // 获取参数
            getParam(mBeanServerConnection, objectName);
            System.out.println("get params======================");
            // 更改参数
            changeParams(mBeanServerConnection, objectName);
            getParam(mBeanServerConnection, objectName);
            System.out.println("set params======================");
    
            useMethod(mBeanServerConnection, objectName);
            getParam(mBeanServerConnection, objectName);
            System.out.println("useMethod.========================");
        }
    
        /**
         * 对method的调用, 采用反射的方式进行
         */
        public static void useMethod(MBeanServerConnection connection, ObjectName objectName) {
            HelloMBean helloMBean = MBeanServerInvocationHandler.newProxyInstance(connection, objectName, HelloMBean.class, true);
            String age = helloMBean.getAge();
            String name = helloMBean.getName();
            helloMBean.setAge("2323223");
            helloMBean.helloWorld("nchar");
        }
    
        /**
         * 可进行相关参数修改
         * 通过setAttribute、getAttrubute方法来进行操作,则属性的首字母要大写
         */
        public static void changeParams(MBeanServerConnection mBeanServerConnection, ObjectName objectName) throws AttributeNotFoundException, InvalidAttributeValueException, ReflectionException, IOException, InstanceNotFoundException, MBeanException {
            mBeanServerConnection.setAttribute(objectName, new Attribute("Name", "hangzhou"));
            mBeanServerConnection.setAttribute(objectName, new Attribute("Age", "1990"));
        }
    
        /**
         * 获取参数
         */
        public static void getParam(MBeanServerConnection connection, ObjectName objectName) throws AttributeNotFoundException, MBeanException, ReflectionException, InstanceNotFoundException, IOException {
            String age = (String) connection.getAttribute(objectName, "Age");
            String name = (String) connection.getAttribute(objectName, "Name");
            System.out.println("name " + name + " age: " + age);
        }
    }

    https://www.cnblogs.com/dongguacai/p/5900507.html

  • 相关阅读:
    USB耳机声卡-音频输入/输出控制器:DP108替代兼容CM108
    关于lora标配SPDT大功率射频开关
    关于2.4G芯片中 CC2500的相关资料
    关于ESP8266EX的一些资料
    【1801日語写作】第11回:5月21日
    【日本語新聞選読】第11回:5月19日
    【1801日語听解4】第11回:5月19日
    【1801日語視聴説2】第11回:5月18日
    【1901日語听解2】第11回:5月18日
    【1701日本語新聞編集】第10回:5月15日
  • 原文地址:https://www.cnblogs.com/wenbronk/p/8535103.html
Copyright © 2011-2022 走看看