JMX

1. JMX简单介绍

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

JConsole和JVisualVM中能够监控到JAVA应用程序和JVM的相关信息都是通过JMX实现的。

先粘一段内容  

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

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

2、JMX架构介绍

基础监测层

  监控层的作用就是使用MBean来监控我们关心的性能指标。因为我们通常关注的性能指标比较多,通常情况下,在监控层我们会有多个MBean,每个MBean监控一类信息。

JMX代理

  JMX代理是内嵌在Java应用程序中的,JMX代理相当于一个容器,所有的MBean都注册到这个容器中,这个容器可以接受外部的请求,返回MBean的监控信息。JMX Agent的核心组件是MBean server,它是一个管理对象的服务器,MBeans在其中注册。一个JMX代理还包括一组用于管理MBeans的服务和至少一个通信适配器(adaptor)或连接器(connector) 以供管理程序访问  

远程管理层

  JMX 可以以多重方式来访问JMX技术监测信息,既可以通过现有的管理协议,比如简单网络管理协议(SNMP),也可以通过专利性的协议。MBean server依赖协议适配器(adaptors)和连接器(connectors)来让JMX代理供管理程序(位于JMX代理所在的JVM之外)访问。
  每个适配器都通过一个特定的协议提供一个包含了所有注册在MBean Server中的MBeans的视图。比如,一个HTML适配器可以在一个浏览器中显示一个MBean。

3、MBean与MXBean的介绍

MBean介绍

 MBean也是JavaBean的一种,在JMX中代表一种可以被管理的资源。一个MBean接口由属性(可读的,可能也是可写的)和操作(可以由应用程序调用)组成。MBean可分为如下四种:

 类型                                                 描述

standard MBean         这种类型的MBean最简单,一个标准的MBean由一个MBean接口(该MBean接口列出了所有被暴露的属性和操作对应的方法)

                和一个class(这 个class实现了这个MBean接口并提供被监测资源的功能)组成(接口和class必须放在同一个包下,不然会出错)。

                它的命名也必须遵循一定的规范,例如我们的MBean为Hello,则接口必须为HelloMBean。标准MBean只能操作基本数据类型,

                如 int、dubbo、lang等。                

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中。后面的例子会有详细介绍

MXBean
  MXBean是MBean的一种,MXBean与MBean一样都需要定义一个接口和class类,但是MXBean并不要求Java类的名称必须与接口名称前部分相同。另外MXBean中还可以正常使用自定义数据类型;
  如果在MBean中使用自定义数据类型的话,通过JConsole查看时会显示不可用。 当MXBean中使用被转换成CompositeDataSupport类

标准MBean与MXBean的区别
  1、在标准MBean中使用自定义数据类型时,JConsole中会显示不可用;而在MXBean中可以正常所使用。
  2、标准的MBean接口与Class的命名必须遵守是一定规范,而MXBean的接口与Class的命名没有约束条件。

4. JMX的使用

标准MBean 使用规范

  标准的MBean由一个MBean接口和一个Class类组成,并且接口必须命名为 xxxMBean 而 Class类名必须为 xxx 放与同一个包下,若不在同一包下运行时将出异常。

JMX的使用步骤
  1. 定义接口与资源实体类,接口中定义属性与操作;get表示可读,set表示可写。
  2. 创建Agent类。
    a. 创建MBeanServer,相当于管理MBean的容器,创建方式有两种一获取JVM中默认启动的Mbean server 或者 自己创建。
    b. 创建ObjectName,用于标识唯一的资源MBean,格式为:"域名:name=MBean名称"。
    c. 绑定MBean与对应的ObjectName并注册到MBeanServer。
  至此即可通过JConsole管理本地的MBean的先关信息了,同事也可以提供其他的连接方式,如:
  3. rmi连接方式。
    a. 注册监听端口号。
    b. 创建JMXServiceURL,格式为:service:jmx:rmi://localhost:0/jndi/rmi://localhost:1099/jmxrmi(完整版) JMXServiceURL格式说明 。
    c. 创建jmxConnectorServer,绑定MBserver与Url。
  4. HtmlAdaptor连接管理方式(需要引入jmxtools.jar)。
    a. 创建Html适配器,并设置监听端口。
    b. 创建适配器ObjectName,绑定Html适配器并注册到MBeanServer。
    c. 开启适配器。

具体使用详情,参考如下代码

public static void init(LoggerContext loggerContext) throws Exception {
mBeanServer = MBeanServerFactory.createMBeanServer(DOMAIN_NAME);
// 注册服务
ObjectName objectName = new ObjectName(DOMAIN_NAME + ":name=" + RELOAD_CONFIG_NAME);
jmxConfigurator = new JMXConfigurator(loggerContext, mBeanServer, objectName);
mBeanServer.registerMBean(jmxConfigurator, objectName); // htmlAdaptor 注册连接
htmlAdaptorServer = new HtmlAdaptorServer();
htmlAdaptorServer.setPort(HTML_PORT);
objectName = new ObjectName(DOMAIN_NAME + ":name=" + CONNECTOR_NAME);
mBeanServer.registerMBean(htmlAdaptorServer, objectName);
htmlAdaptorServer.start(); // rmi方式
//这句话非常重要,不能缺少!注册一个端口,绑定url后,客户端就可以使用rmi通过url方式来连接JMXConnectorServer
LocateRegistry.createRegistry(RMI_PORT);
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + RMI_PORT + "/logback_config");
jmxConnectorServer = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mBeanServer);
jmxConnectorServer.start();
}

5、JMXServiceURL格式说明
  (1)service:jmx:rmi://localhost:0/jndi/rmi://localhost:1099/jmxrmi
  蓝色部分可以省略掉
  (2)service:jmx: 这个是JMX URL的标准前缀,所有的JMX URL都必须以该字符串开头,否则会抛MalformedURLException
  (3)rmi: 这个是jmx connector server的传输协议,在这个url中是使用rmi来进行传输的
  (4)localhost:0 这个是jmx connector server的IP和端口,也就是真正提供服务的host和端口,可以忽略,那么会在运行期间随意绑定一个端口提供服务
  (5)jndi/rmi://localhost:1099/jmxrmi 这个是jmx connector server的路径,具体含义取决于前面的传输协议。比如该URL中这串字符串就代表着该jmx connector server的stub是使用 jndi api 绑定在 rmi://localhost:1099/jmxrmi 这个地址

实际演示操作:

1. Mbean准备  先建立需要连接的接口

package com.gdut.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.gdut.jmx;

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");
}
}

3.使用java命令行指定

package com.gdut.jmx;

import java.lang.management.ManagementFactory;

import javax.management.InstanceAlreadyExistsException;
import javax.management.MBeanRegistrationException;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectInstance;
import javax.management.ObjectName; 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.gdut.jmx:name=" + hello.getClass().getName()); ObjectInstance objectInstance = server.registerMBean(hello, helloName); Thread.sleep(60*1000*1000);
}
}

为Java程序开启JMX很简单,只要在运行Java程序的命令后面指定如下命令即可

-Dcom.sun.management.jmxremote

-Dcom.sun.management.jmxremote.port=8011

-Dcom.sun.management.jmxremote.ssl=false

-Dcom.sun.management.jmxremote.authenticate=false

如果是使用eclipse开发测试,可以再eclipse 启动java项目默认没有开启jmx远程查看功能,如果需要看项目运行的线程内存使用量等信息,可以在eclipse启动参数中增加:(也可以单独配置选项的jconsole信息,在run-》run configurations-》选择对应的java application-》选择arguments选项-》在VM arguments中添加上面对应信息)

使用jconsole工具使用进行监控

 Jconsole,Java Monitoring and Management Console。

 Jconsole是JDK自带的监控工具,在JDK/bin目录下可以找到。它用于连接正在运行的本地或者远程的JVM,对运行在java应用程序的资源消耗和性能进行监控,并画出大量的图表,提供强大的可视化界面。而且本身占用的服务器内存很小,甚至可以说几乎不消耗。

  JConsole 是一个内置 Java 性能分析器,可以从命令行(直接输入jconsole)或在 GUI shell (jdk\bin下打开)中运行。

  它用于对JVM中内存,线程和类等的监控。可使用JTop插件。它可以监控本地的jvm,也可以监控远程的jvm,也可以同时监控几个jvm。

  这款工具的好处在于,占用系统资源少,而且结合Jstat,可以有效监控到java内存的变动情况,以及引起变动的原因。在项目追踪内存泄露问题时,很实用。

windows下直接cmd中输入:JConsole 后就可以弹出:

进去之后

可以通过操作MBean里面的属性和方法

console输出:

console输出:

关于Jconsole请看这两篇:

   Jconsole与Jmx 分析JVM状况(上)

     Jconsole与Jmx 分析JVM状况(下)

出处: JMX详解详细介绍及使用

   JMX超详细解读

JMX jconsole 的使用的更多相关文章

  1. java head space/ java.lang.OutOfMemoryError: Java heap space内存溢出

    上一篇JMX/JConsole调试本地还可以在centos6.5 服务器上进行监控有个问题端口只开放22那么设置的9998端口 你怎么都连不上怎么监控?(如果大神知道还望指点,个人见解) 线上项目出现 ...

  2. Tomcat 基础优化

    作者:北京运维 本文档是身边一些朋友.技术大佬之前分享的一些笔记,记录了 Tomcat 优化方法,笔记较多而且比较杂乱,经过整理.分类我个人觉得大致可以从以下几个方面优化 Tomcat: Tomcat ...

  3. 本文分享一下ehcache的使用心得,本文主要讲以广播的形式同步缓存。

    本文分享一下ehcache的使用心得,本文主要讲以广播的形式同步缓存. 下面讲述主要分为两个部分,一个是配置文件,一个是Java代码. 1.准备jar包: slf4j-api-1.7.12.jar,e ...

  4. Using jconsole to connect to JMX on AS7

    Using jconsole to connect to JMX on AS7 https://developer.jboss.org/wiki/UsingJconsoleToConnectToJMX ...

  5. Jconsole与Jmx 分析JVM状况(下) 转

    出处: Jconsole与Jmx 分析JVM状况(下) 线程(ThreadMXBean ) 从 Jconsole 画面取得线程画面如下: 左下角列出了所以正在运行的线程.通过点击某个线程,右下脚可以看 ...

  6. Jconsole与Jmx 分析JVM状况(上) 转

    出处:Jconsole与Jmx 分析JVM状况(上) JVM 平台提供 Mbeans 说明 在 Java 2 平台 5.0 以上版本,有一组 API 可以让 Java 应用程序和允许的工具监视和管理  ...

  7. JConsole、VisualVM 依赖的 JMX 技术到底是什么

    我是风筝,公众号「古时的风筝」,一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在 ...

  8. jconsole远程连接 jmx配置注意事项

    由于在测试程序时需要收集程序运行时的内存,CPU等消耗情况.选择了jconsole这个jdk自带工具来观察.为了不影响程序运行状态,用远程连接的方式来具体观察. 首先,程序是放在ubutun系统服务器 ...

  9. java使用jconsole查看java程序运行(jmx原理)

    在JVM启动参数上加上     java -Dcom.sun.management.jmxremote.port=8999     -Dcom.sun.management.jmxremote.aut ...

随机推荐

  1. Linux网络编程二、tcp连接API

    一.服务端 1.创建套接字: int socket(int domain, int type, int protocol); domain:指定协议族,通常选用AF_INET. type:指定sock ...

  2. P1598 垂直柱状图

    输入格式: 四行字符,由大写字母组成,每行不超过100个字符 输出格式: 由若干行组成,前几行由空格和星号组成,最后一行则是由空格和字母组成的.在任何一行末尾不要打印不需要的多余空格.不要打印任何空行 ...

  3. xcode6 如何编译64位iOS应用

    原文:http://mobile.51cto.com/hot-412500.htm 随着iPhone5S的推出,大家开始关心5S上所使用的64位CPU A7. 除了关心A7的性能以外,大家还会关心一个 ...

  4. C++入门经典-例7.10-运算符的重载,重载加号运算符

    1:曾经介绍过string类型的数据,它是C++标准模版库提供的一个类.string类支持使用加号“+”连接两个string对象.但是使用两个string对象相减确实非法的,其中的原理就是C++所提供 ...

  5. laravel 框架接入环信遇到的坑(-)

    在脚本中执行判断user表中是否注册环信时,报错: “请求错误:service_resource_not_found Service resource not found  ” // 判断环信是否已经 ...

  6. Android jni/ndk编程四:jni引用类型

    一.JNI引用类型 JNI支持三种类型的 opaque reference:local references, global references,和weak global references,下面 ...

  7. 路由设置中"DHCP服务器"启用或不启用是干嘛的?

    “DHCP服务器”启用的话,每一台连接这个路由器的电脑都会自动获取一个IP地址,并且不会跟其他电脑的想冲突:“DHCP服务器”不启用就必须手动给每一台连接这个路由器的电脑设置本地连接里面的“inter ...

  8. Python 中的type和object详解

    1.python中的类 Python2.x 中的类分为两种,一种是所有继承自object的新式类,另外一种是经典类classobj, 新式类的写法: class A(object): pass 经典类 ...

  9. 小D课堂 - 新版本微服务springcloud+Docker教程_1_02技术选型

    笔记 2.技术选型和学后水平     简介:课程所需基础和技术选型讲解,学完课程可以到达怎样的程度,          1.IDEA JDK8 Maven SpringBoot基础 Linux 2.理 ...

  10. Rxjava2实战--第三章 创建操作符

    Rxjava2实战--第三章 创建操作符 Rxjava的创建操作符 操作符 用途 just() 将一个或多个对象转换成发射这个或者这些对象的一个Observable from() 将一个Iterabl ...