`
程序新手
  • 浏览: 58443 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

运用JMX远程监控、管理JVM

阅读更多

问题背景讨论:在JAVA运行时,对JVM系统的检测、管理是开发同学一直期望的,目前有一些开源产品开源针对JVM进行监控,例如javamelody等等,这样框架虽然好,但是如果使用会带来一些问题。第一:由于javamelody入口是一个filter,所以会带来性能问题、第二:如果应用服务器很多,会缺乏统一管理,此外安全性、爬虫等等问题略过不提
     JDK自带了故障检测工具Jconsole和1.6出来的Jvisualvm都可以远程对服务器进行监控,后者甚是提供可以在线得到ThreadDump和HeapDump文件,更是提供了可扩展插件功能(虽然可能会影响jvm服务器性能)
    但现状很多公司都有自己的运维团队,未必会把线上服务器的权限交给我们开发同学,所以有必要了解JAVA远程管理方面的知识,假设如果在后台有一套系统,可以管理、监控我们线上所有java服务器,如果出现问题不需要对每个服务器进行排查而是直接从列表中获取、定位到信息,岂不是一件很幸福的事情~

    书归正文,分享下近几天在JMX方面的知识,JDK的API中翻译过来对javax.management的描述

     提供 Java Management Extensions 的核心类。
     Java Management Extensions (JMXTM) API 是一个用于管理和监视的标准 API。典型用途包括:
       1) 查询并更改应用程序配置
       2) 累积有关应用程序行为的统计数据并使其可用
       3) 通知状态更改及错误状况。
       4) JMX API 还可以作为解决方案的一部分来管理系统、网络等。
       5) API 包括远程访问,远程管理程序可以基于这些目的与正在运行的应用程序进行交互。
     JMX核心类为Mbean。MBean 是表示资源的指定管理对象。它有一个管理接口,该接口包括以下内容:
       1) 可以读取和/或写入的指定名称和类型的属性 
       2) 可以调用的指定名称和类型的操作
       3) 可以由 MBean 发送的指定类型的通知。
     推荐一篇文章可以让大家入门
     http://www.ibm.com/developerworks/cn/java/j-lo-jse63/
   
     配置远程连接tomcat需要在tomcat所在服务器修改几个配置
      1) 修改JMX配置
      进入JAVA_HOME/jre/lib/management路径下面
      将jmxremote.password.template改成jmxremote.password,将内容中的monitorRole  QED的注释去掉
      将management.properties中的com.sun.management.jmxremote.port=(改成你想要的JMX端口号)
将  com.sun.management.jmxremote.ssl=false、                                                      com.sun.management.jmxremote.authenticate=false注释打开
     注意:linux下需要该权限,chmod 600 jmxremote.access, chmod 600 jmxremote.password
    window下特麻烦,现需要jdk装在NTFS文件系统下,选中文件,点右键“属性”-〉安全,点“高级”,去掉“从父项继承....”,弹出窗口中选“删除”,这样删除了所有访问权限。再选“添加”-〉高级,“立即查找”,选中你的用户,例administrator,点“确定",“确定"。来到权限窗口,勾选"完全控制",点"确定",OK了。
     用jconsole连接远程linux服务时, IP地址和port都输入正确的情况下,仍然是连接失败
vi /etc/hosts,将hostname对应的ip改为真实ip
     2) 修改tomcat启动参数
     windows下面为catalina.bat、linux下面为cataina.sh
    set CATALINA_OPTS=-Dcom.sun.management.jmxremote
    -Dcom.sun.management.jmxremote.port="JMXport"
    -Dcom.sun.management.jmxremote.ssl=false
    -Dcom.sun.management.jmxremote.authenticate=false

     如果不修改的时候默远程连接不上,远程连接的通过IP和JMX端口找到JVM虚拟机后无法定位具体哪个应用使用JMX端口,所以只有在启动tomcat情况后占用JMX

   关于配置JMX,可以具体参考http://download.oracle.com/javase/1.5.0/docs/guide/management/agent.html#remote
   
   实战远程连接TOMCAT
   1) 获取连接 
  

private static void getConnection() throws Exception {   
  
    //用户名、密码   
                 Map<String, String[]> map = new HashMap<String, String[]>();   
    map   
            .put("jmx.remote.credentials", new String[] { "monitorRole",   
                    "QED" });   
    String jmxURL = "service:jmx:rmi:///jndi/rmi://192.168.0.100:1000/jmxrmi";   
       
    JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);   
    connector = JMXConnectorFactory.connect(serviceURL, map);   
    mbsc = connector.getMBeanServerConnection();   
  
}   

  2) 获取所有的objectName

   Set MBeanset = mbsc.queryMBeans(null, null);   
Iterator MBeansetIterator = MBeanset.iterator();   
while (MBeansetIterator.hasNext()) {   
    ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator   
            .next();   
    ObjectName objectName = objectInstance.getObjectName();   
    MBeanInfo objectInfo = mbsc.getMBeanInfo(objectName);   
    System.out.print("ObjectName:" + objectName.getCanonicalName()   
            + ".");   
    System.out.print("mehtodName:");   
    for (int i = 0; i < objectInfo.getAttributes().length; i++) {   
        System.out.print(objectInfo.getAttributes()[i].getName() + ",");   
    }   
    System.out.println();   
}   

 

3) 获取堆内存信息

 ObjectName heapObjName = new ObjectName("java.lang:type=Memory");   
  
//堆内存   
MemoryUsage heapMemoryUsage = MemoryUsage   
.from((CompositeDataSupport) mbsc.getAttribute(heapObjName,   
        "HeapMemoryUsage"));   
long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配   
long usedMemory = heapMemoryUsage.getUsed();   
System.out.print("堆内存总量:"+heapMemoryUsage.getMax()/1024+"KB,当前分配量:"+commitMemory/1024+"KB,当前使用率:"+usedMemory/1024+"KB,");   
System.out.println("堆内存使用率:" + (int) usedMemory * 100  
        / commitMemory + "%");// 堆使用率   
  
      //栈内存   
        MemoryUsage nonheapMemoryUsage = MemoryUsage   
        .from((CompositeDataSupport) mbsc.getAttribute(heapObjName,   
                "NonHeapMemoryUsage"));   
        long noncommitMemory = nonheapMemoryUsage.getCommitted();   
long nonusedMemory = heapMemoryUsage.getUsed();   
  
System.out.println("栈内存使用率:" + (int) nonusedMemory * 100  
        / noncommitMemory + "%");   
           
//PermGen内存   
        ObjectName permObjName = new ObjectName(   
"java.lang:type=MemoryPool,name=Perm Gen");   
  
MemoryUsage permGenUsage = MemoryUsage   
        .from((CompositeDataSupport) mbsc.getAttribute(permObjName,   
                "Usage"));   
long committed = permGenUsage.getCommitted();// 持久堆大小   
long used = heapMemoryUsage.getUsed();//     
System.out.println("perm gen:" + (int) used * 100 / committed   
        + "%");// 持久堆使用率 

 

4) 获取堆中伊甸区

ObjectName youngHeapObjName = new ObjectName("java.lang:type=MemoryPool,name=Eden Space");   
    // 获取Mbean对象   
    MBeanInfo youngHeapInfo = mbsc.getMBeanInfo(youngHeapObjName);   
    // 获取对象的属性   
    MBeanAttributeInfo[] youngHeapAttributes = youngHeapInfo.getAttributes();   
           
    MemoryUsage youngHeapUsage = MemoryUsage   
                .from((CompositeDataSupport) mbsc.getAttribute(youngHeapObjName, "Usage"));   
           
       System.out.print("目前新生区分 配最大内存:"+youngHeapUsage.getMax()/1024+"KB,");   
       System.out.print("新生区已分配:"+youngHeapUsage.getCommitted()/1024+"KB,");   
       System.out.print("新生区初始化:"+youngHeapUsage.getInit()/1024+"KB,");   
       System.out.println("新生区已使用"+youngHeapUsage.getUsed()/1024+"KB");   
     

 

5) 获取线程

ObjectName managerObjName = new ObjectName(   
                "Catalina:type=Manager,*");   
        Set<ObjectName> s = mbsc.queryNames(managerObjName, null);   
        for (ObjectName obj : s) {   
               
            ObjectName objname = new ObjectName(obj.getCanonicalName());   
            System.out.print("objectName:"+objname);   
            System.out.print(",最大会话数:"  
                    + mbsc.getAttribute(objname, "maxActiveSessions")+",");   
            System.out.print("会话数:"  
                    + mbsc.getAttribute(objname, "activeSessions")+",");   
            System.out.println("活动会话数:"  
                    + mbsc.getAttribute(objname, "sessionCounter"));  

 

由于可以获取的信息很多,暂不全部列出来 
翻过头来看下tomcat对JMX的支持


     看完上面最后一段话,有没有一种很雷人的感觉

     关于tomcat对JMX的支持可以看下详细的文档
     http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html
    
     当我们默认直接访问tomcat提供的JMX接口时(http://localhost:8080/manager/jmxproxy/?qry=)会出现所有的MBeans,

 

 如果想要具体的MBeans只需要将其name后面的值放在url的后面  


  因此,在默认情况下我们看到的信息都可以通过远程方式获取到,下一篇会介绍如何远程管理Tomcat

  • 大小: 395.4 KB
  • 大小: 57 KB
  • 大小: 157.9 KB
2
1
分享到:
评论
2 楼 JavaCrazyer 2013-01-05  
额,其实没必要这么麻烦,tomcat管理页面就有这些功能。如果需要更多信息,只需要写个JSP,调用JDK自带的
RuntimeMXBean runtime =  ManagementFactory.getRuntimeMXBean() ;
// ManagementFactory.getThreadMXBean() 方法或从平台 MBeanServer 方法获得它。ThreadMXBean mb = ManagementFactory.getThreadMXBean();
//
MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans() ;
通过这些代码继续扩展你能获得更多服务器上的信息
1 楼 lnfszl 2012-04-11  
请问有没有研究过,开启JMX会不会对jvm带来性能问题

相关推荐

    tomcat-catalina-jmx-remote-8.0.9.jar

    当你想深入学习jvm的时候,肯定会用到。用于使用jvisualvm.exe远程监控服务器jvm

    JConsole_远程监控Tomcat_ricky

    JConsole是一个基于JMX的GUI工具,用于连接正在运行的JVM,不过此JVM需要使用可管理的模式启动。如果要把一个应用以可管理的形式启动,可以在启动是设置com.sun.management.jmxremote。JConsole能够提供被监控虚拟机...

    Java虚拟机监控方案.docx

     通过向远程虚拟机内部JMX代理注册各种服务来获取虚拟机的信息以及虚机上的应用程序信息,所有的监控过程不用依靠应用来提供信息  通过虚拟机内置的jstat指令获取内存各种堆和非堆的大小及其内存使用量  通过...

    jolokia:辣椒素上的JMX

    Jolokia是一种远程访问JMX MBean的新方法。 它与JSR-160连接器的不同之处在于它是一种基于代理的方法,该方法使用REST风格的HTTP上的JSON进行通信。 为不同的环境提供了多个代理: 用于在Java EE Server中作为Web...

    mycat-web:mycat监控系统

    Mycat网站 Mycat-web是对mycat-server提供监视服务。...他基于jmx对所有JVM监视。通过JDBC连接对Mycat,Mysql监视。基于snmp协议,监视远程服务器(目前仅限于于linux系统)的cpu,内存,网络,磁盘。

    Hadoop权威指南 第二版(中文版)

     Java管理扩展(JMX)  维护  日常管理过程  委任节点和解除节点  升级 第11章 Pig简介  安装与运行Pig  执行类型  运行Pig程序  Grunt  Pig Latin编辑器  示例  生成示例  与数据库比较  PigLatin  ...

    Hadoop权威指南(中文版)2015上传.rar

    Java管理扩展(JMX) 维护 日常管理过程 委任节点和解除节点 升级 第11章 Pig简介 安装与运行Pig 执行类型 运行Pig程序 Grunt Pig Latin编辑器 示例 生成示例 与数据库比较 PigLatin 结构 语句 表达式 1.4.4 类型 ...

    java开源包1

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包11

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包2

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包3

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    JAVA上百实例源码以及开源项目

    2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户...

    java开源包6

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包5

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包10

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包4

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包8

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包7

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    java开源包9

    MyBatchFramework 是一个开源的轻量级的用以创建可靠的易管理的批量作业的Java包,主要特点是多线程、调度、JMX管理和批量执行报表,执行历史等。 SIP协议包 jSIP.tar jSIP这个Java包目标是用Java实现SIP(SIP:...

    JAVA上百实例源码以及开源项目源代码

    2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户...

Global site tag (gtag.js) - Google Analytics