先粘一段内容
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 interfaceHelloMBean {publicString getName();public voidsetName(String name);publicString getAge();public voidsetAge(String age);public voidhelloWorld();public voidhelloWorld(String str);public voidgetTelephone();
}
2, 实体类继承
package com.wenbronk.le.iris.jmx;
import ch.qos.logback.core.joran.spi.NoAutoStart;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;/**
* 必须实现 Mbean, 才可以进行注册*/@NoArgsConstructor
@AllArgsConstructorpublic classHello implements HelloMBean {privateString name;privateString age;
@OverridepublicString getName() {
System.out.println("get name::" +name);returnname;
}
@Overridepublic voidsetName(String name) {this.name =name;
System.out.println("set name" +name);
}
@OverridepublicString getAge() {
System.out.println("get age::" +age);returnage;
}
@Overridepublic voidsetAge(String age) {this.age =age;
System.out.println("set age" +age);
}
@Overridepublic voidhelloWorld() {
System.out.println("hello world");
}
@Overridepublic voidhelloWorld(String str) {
System.out.println("hello world" +str);
}
@Overridepublic voidgetTelephone() {
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 classHelloAgent {public static voidmain(String[] args) throws MalformedObjectNameException, NotCompliantMBeanException, InstanceAlreadyExistsException, MBeanRegistrationException, InterruptedException {
MBeanServer server=ManagementFactory.getPlatformMBeanServer();
Hello hello= newHello();//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 readonlyadmin readwrite
jmx.password
monitor com.le.big
admin com.le.big
启动参数指定:
JMX_PORT=12345JAVA_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 classHelloAgentRemote {public static voidmain(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= newTesttt();
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 classClient {public static voidmain(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 voiduseMethod(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 voidchangeParams(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 voidgetParam(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