作者:wuxinliulei
链接:https://www.zhihu.com/question/36688387/answer/68667704
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

JMX是一种JAVA的正式规范,它主要目的是让程序有被管理的功能。

那么怎么理解所谓的“被管理”呢?试想你开发了一个软件(如WEB网站),它是在24小时不简断运行的,那么你可能会想要“监控”这个软件的运行情况,比如收到了多少数据,有多少人登录等等。或者你又想“配置”这个软件,比如现在访问人数比较多,你想把数据连接池设置得大一些;每天的UV、PV是多少;又或者在业务高峰的期间,你想对接口进行限流,就必须去修改接口并发的配置值。

  应用场景:中间件软件WebLogic的管理页面就是基于JMX开发的,而JBoss则整个系统都基于JMX构架。

对于一些参数的修改,网上有一段描述还是比较形象的:

1、程序初哥一般是写死在程序中,到要改变的时候就去修改代码,然后重新编译发布。

2、程序熟手则配置在文件中(JAVA一般都是properties文件),到要改变的时候只要修改配置文件,但还是必须重启系统,以便读取配置文件里最新的值。

3、程序好手则会写一段代码,把配置值缓存起来,系统在获取的时候,先看看配置文件有没有改动,如有改动则重新从配置里读取,否则从缓存里读取。

4、程序高手则懂得物为我所用,用JMX把需要配置的属性集中在一个类中,然后写一个MBean,再进行相关配置。另外JMX还提供了一个工具页,以方便我们对参数值进行修改。

让开发者和管理者可以获取程序运行的状态以及动态的修改程序的相关配置。

SUN依据这个规范在JDK提供了JMX接口,而根据这个接口的实现则有很多种,比如Weblogic的JMX实现、MX4J、JBoss的JMX实现。

我们经常使用的JDK中SUN公司的实现在java.lang.management包下。

JMX架构图:

MBean 即 managed beans 被管理的Beans

从图中我们可以看到,JMX的结构一共分为三层:

1、基础层:主要是MBean,被管理的资源。

MBean分为如下四种,我接下来主要介绍standard MBean

类型描述standard MBean这种类型的MBean最简单,它能管理的资源(包括属性,方法,时间)必须定义在接口中,然后MBean必须实现这个接口。它的命名也必须遵循一定的规范,例如我们的MBean为Hello,则接口必须为HelloMBean。dynamic MBean必须实现javax.management.DynamicMBean接口,所有的属性,方法都在运行时定义open MBean此MBean的规范还不完善,正在改进中model MBean与标准和动态MBean相比,你可以不用写MBean类,只需使用javax.management.modelmbean.RequiredModelMBean即可。RequiredModelMBean实现了ModelMBean接口,而ModelMBean扩展了DynamicMBean接口,因此与DynamicMBean相似,Model MBean的管理资源也是在运行时定义的。与DynamicMBean不同的是,DynamicMBean管理的资源一般定义在DynamicMBean中(运行时才决定管理那些资源),而model MBean管理的资源并不在MBean中,而是在外部(通常是一个类),只有在运行时,才通过set方法将其加入到model MBean中。后面的例子会有详细介绍

2、适配层:MBeanServer,主要是提供对资源的注册和管理。

3、接入层:提供远程访问的入口。

JMX超详细解读 - 冬瓜蔡 - 博客园 这篇博客详细介绍了三种使用JMX的方式,下面我提供一下自己实现的例程

import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;import com.sun.jdmk.comm.HtmlAdaptorServer;public class ApplicationServer
{private static HtmlAdaptorServer adaptorServer = null;private static javax.management.remote.JMXConnectorServer cs = null;private static Logger logger = null;private static ExecutorService cachedExecutors = null;private static void initExecutor(){cachedExecutors = Executors.newFixedThreadPool(2);}private static void exitExecutor(){cachedExecutors.shutdown();}public static void execute(final Runnable runnable){cachedExecutors.execute(runnable);}private static void initLogger(){System.out.println("configuring log4j with log4j.xml");DOMConfigurator.configure("log4j.xml");logger = Logger.getLogger("root");}private static void initHtmlJMX() throws Exception{MBeanServer server = MBeanServerFactory.createMBeanServer();ObjectName helloName = new ObjectName("jmx:name=HelloWorld");server.registerMBean(new Hello(), helloName);ObjectName adapterName = new ObjectName("HelloAgent:name=htmladapter,port=8081");adaptorServer = new HtmlAdaptorServer();server.registerMBean(adaptorServer, adapterName);adaptorServer.start();logger.info("start jmx html server");}private static int initProtogenesisJMX() throws Exception{String port1Str = System.getProperty("com.jmxport1");String port2Str = System.getProperty("com.jmxport2");if (port1Str == null || port2Str == null){logger.error("jmx端口未通过系统属性设置");return -1;}final int port1 = Integer.valueOf(port1Str);final int port2 = Integer.valueOf(port2Str);System.setProperty("java.rmi.server.randomIDs", "true");try{LocateRegistry.createRegistry(port2);}catch (java.rmi.server.ExportException ex){logger.error("err", ex);return -1;}MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();java.util.HashMap<String, Object> env = new java.util.HashMap<String, Object>();env.put("jmx.remote.x.password.file", "jmxremote.password");env.put("jmx.remote.x.access.file", "jmxremote.access");JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://127.0.0.1:" + port1 + "/jndi/rmi://127.0.0.1:" + port2+ "/jmxrmi");cs = JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);try{cs.start();}catch (java.net.BindException ex){logger.error("端口已被占用", ex);return -2;}return 0;}public static void exitHtmlJMX(){adaptorServer.stop();}public static void exitProtogenesisJMX() throws IOException{cs.stop();}public static void init() throws Exception{initLogger();// initHtmlJMX();initProtogenesisJMX();initExecutor();}public static void exit() throws IOException{//exitHtmlJMX();exitProtogenesisJMX();exitExecutor();}public static void main(String[] args) throws Exception{System.setProperty("com.jmxport1", String.valueOf(7000));System.setProperty("com.jmxport2", String.valueOf(7001));init();MBeanServer server = java.lang.management.ManagementFactory.getPlatformMBeanServer();ObjectName helloName = new ObjectName("jmxBean:name=stopper");server.registerMBean(new Stopper(), helloName);}public interface StopperMBean{void stop() throws IOException;}public static class Stopper implements StopperMBean{public void stop() throws IOException{ApplicationServer.exit();}}}
import java.text.SimpleDateFormat;
import java.util.HashMap;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*            host port username password bean name method ...params* @throws Exception*/public static void main(String[] args) throws Exception{if ((args.length < 6) || (args.length % 2 != 0)){logErr("params error");return;}final String host = args[0];final int rmiPort = Integer.valueOf(args[1]).intValue();final String username = args[2];final String password = args[3];final ObjectName objectName = new ObjectName(args[4]);final String methodName = args[5];final HashMap<String, String[]> jmxParamsHashMap = new HashMap<String, String[]>();final String[] usernameAndPassword ={ username, password };jmxParamsHashMap.put("jmx.remote.credentials", usernameAndPassword);final String serviceUrl = new StringBuilder().append("service:jmx:rmi:///jndi/rmi://").append(host).append(":").append(rmiPort).append("/jmxrmi").toString();final JMXServiceURL jmxServiceURL = new JMXServiceURL(serviceUrl);final JMXConnector jmxConnector = JMXConnectorFactory.connect(jmxServiceURL, jmxParamsHashMap);if (jmxConnector == null){logErr(new StringBuilder().append("connect to jmx failed, url=").append(jmxServiceURL).toString());return;}log(new StringBuilder().append("JMXConnector=").append(jmxConnector.toString()).toString());Object[] paramsValue = null;String[] paramsClassName = null;final MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();final Object localObject = mBeanServerConnection.invoke(objectName, methodName, paramsValue, paramsClassName);log(new StringBuilder().append("invoke method success, name=").append(objectName).append(", operation=").append(methodName).append(", retvalue=").append(localObject == null ? "void" : localObject.toString()).toString());}static void log(String paramString){final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss : ");final StringBuilder sBuilder = new StringBuilder();sBuilder.append(simpleDateFormat.format(Long.valueOf(System.currentTimeMillis())));sBuilder.append(paramString);System.out.println(sBuilder.toString());}static void logErr(String paramString){final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss : ");final StringBuilder sBuilder = new StringBuilder();sBuilder.append(simpleDateFormat.format(Long.valueOf(System.currentTimeMillis())));sBuilder.append(paramString);System.err.println(sBuilder.toString());}
}

from:https://www.zhihu.com/question/36688387

Java中JMX管理器的作用,项目中有什么具体使用?相关推荐

  1. java中布局管理器的作用_使用Java布局管理器的目的是什么?

    当您使用layout时,调用pack()"使此窗口的大小适合其子组件的首选大小和布局."如果不这样做,则必须尝试自己计算边界.如果(当)你弄错了,如下面有点人为的例子所示,用户会责 ...

  2. java中布局管理器flowlayout,在Java中下列()方法可以把JFrame的布局管理器设为FlowLayout类型。...

    在Java中下列()方法可以把JFrame的布局管理器设为FlowLayout类型. 答:jFrame.setLayout(new FlowLayout() ) 在Word 2010的编辑状态,当前编 ...

  3. java中布局管理器flowlayout_JAVA基础:FlowLayout布局管理器

    在前面的例子中,使用到了FlowLayout布局管理器.FlowLayout型布局管理器对容器中组件进行布局的方式是将组件逐个地安放在容器中的一行上.一行放满后就另起一个新行. FlowLayout有 ...

  4. java的布局管理器_Java中提供了几种布局管理器

    近日,很多网友都在关注Java中提供了几种布局管理器这个话题,那么Java中提供了几种布局管理器具体情况是怎么样的呢?Java中提供了几种布局管理器的相关信息有哪些?下面的内容是小编为大家找到的关于J ...

  5. 接口测试--apipost中cookie管理器的使用

    在学习apipost中cookie管理器如何使用之前,我们先了解一下什么是cookie,cookie有什么组成,各自代表的什么含义. 一.什么是cookie Cookie 的本职工作并非本地存储,而是 ...

  6. Java 中finalize()方法起什么作用呢?

    转自: Java 中finalize()方法起什么作用呢? Java之finalize()方法功能说明 当我们在一个类中定义了finalize()方法时, 如果一个对象被垃圾收集器析构(回收)之前,则 ...

  7. Java Swing布局管理器(详解版)

    在使用 Swing 向容器添加组件时,需要考虑组件的位置和大小.如果不使用布局管理器,则需要先在纸上画好各个组件的位置并计算组件间的距离,再向容器中添加.这样虽然能够灵活控制组件的位置,实现却非常麻烦 ...

  8. Spring中的拦截器的作用

    Spring中的拦截器的作用 SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理. 用户可以自己定义一些拦截器来实现特定的功能. 谈到拦截器 ...

  9. Java GUI-布局管理器

    Swing组件不能单独存在,必须放置于容器当中,组件在容器中的位置和尺寸是由布局管理器来决定的. Swing提供了8种布局管理器,分别是BorderLayout(边界布局管理器),BoxLayout( ...

最新文章

  1. Servlet生命周期与工作原理
  2. 谈谈android反编译和防止反编译的方法
  3. 打开和关闭mysql服务器_启动和关闭MySQL服务器
  4. 数据表格+弹出层的综合案例
  5. python hack库_常用的Python库
  6. Js中fetch方法
  7. 预测评价系统_「机器学习」一文读懂分类算法常用评价指标
  8. VUE使用过滤器来格式化当前时间
  9. nginx反向代理docker registry报”blob upload unknown解决办法
  10. LabVIEW 2021 工具包
  11. 算法基本知识,入门必备
  12. matlab怎么导入程序出错,Matlab导入数据时出错!十分困扰!
  13. 双碳目标下综合能源系统低碳运行优化调度Matlab程序,包含光伏、风电、热电联产、燃气锅炉、电锅炉、电
  14. asm MGMT库迁移
  15. SQL Server 数据库作业(备份、同步)
  16. ​基于光通信的6G水下信道建模综述
  17. ios申请企业开发者账号的代理_iOS企业级开发者账号申请
  18. 记录一次jar文件在windows系统下开机自启
  19. Qt的长期支持版本的知识搜集
  20. RDD与MapReduce对比

热门文章

  1. weblogic升级之ddconverter
  2. 一台加密货币ATM机月营收额高达3万美金
  3. Spring Cloud Alibaba - 07 Ribbon 应用篇及内置的负载均衡算法
  4. 白话Elasticsearch72_利用HDFS备份与恢复ES生产集群的数据
  5. Spring Boot2.x-08Spring Boot2.1.2 整合 Mybatis1.3.2 + 通用Mapper2.1.4 + PageHelper1.2.10 + Druid 1.1.10
  6. 实战SSM_O2O商铺_47【Redis缓存】清除缓存接口的开发
  7. 记一次Weblogic连接池泄露的修复过程
  8. pyhton 反转单词顺序
  9. java 枚举类型的使用_JAVA 枚举类型使用
  10. python中对字典进行排序_python如何给字典排序