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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM