使用JConsole实现JBoss性能监控
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
jconsole
功能简介
jconsole是JDK5开始自带的基于GUI的JVM监控工具,可以监控内存、线程、jvm堆栈、执行GC等,不仅可以对本机JVM进行监控,也可用于远程主机的JVM。
下面就来说一下在JBOSS运行环境下如何使用jconsole进行监控。
首先,配置jboss启动参数,jboss4.2x中,可以打开run.bat文件。
set JA V A_OPTS=%JA V A_OPTS% -Djava.rmi.server.hostname=10.5.35.151 -Dcom.sun.management.jmxremote.port=8950
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=fals
其中:
-Djava.rmi.server.hostname=10.5.35.151 设置访问的主机地址
-Dcom.sun.management.jmxremote.port=8950 设置端口
-Dcom.sun.management.jmxremote.authenticate=false 不需要认证
-Dcom.sun.management.jmxremote.ssl=false 不需要SSL
如果需要设置用户名和密码,
则-Dcom.sun.management.jmxremote.authenticate=true
同时还要设置密码文件
-Dcom.sun.management.jmxremote.password.file=$JA V A_HOME/jre/lib/management/j mxremote.password
在jmxremote.password文件中增加用户名密码即可。
然后双击run.bat ,启动jboss.
在客户端机器上键入:cmd-> jconsole 10.5.35.151:8950,之后就会出现监控控制台,如下图:
这里有六个tab页,分别对内存、线程、类等都有监控,非常方便。
一般情况下,使用这种方式观察内存使用情况,线程是否有死锁等等。
系统设置
1.首先什么都不用装哦,只要你本机有jdk;
2.echo $JA V A_HOME,找出java安装路径;
3.自己寻觅一个路径mkdir jcon_pwd,我们暂时命名为$your_path/jcon_pwd;
4.执行
cp $JA V A_HOME/jre/lib/management/jmxremote.pwd.template
$your_path/jcon_pwd/jmxremote.pwd;
5.vi jmxremote.pwd,修改monitorRole *****(your password);
6.在env.sh文件中的JA V A_OPTS参数中,加入:
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.pwd.file=/home/zhao/brmms/deploy/bin/jcon_pwd/jmxremot e.pwd -Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
注意port=9999,要是一个没有人使用的端口。
7.执行hostname -i ,如果显示的是127.0.0.1,需要修改/etc/hosts文件
#127.0.0.1 localhost localhost.localdomain localhost
<server ip> localhost localhost.localdomain localhost
8. 检查vi /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=主机名//在这里可以修改主机名
9.启动jboss server,./startws.sh -d<serverip>
stat -na|grep <listenport>, 如netstat -na |grep 9999 查看后为listen状态;
11.打开客户端%JA V A_HOME%/bin,双击打开jconsole.exe
12.指定连接参数:
远程主机: 服务器的真实IP地址
端口: port($JA V A_OPTIONS中-Dcom.sun.management.jmxremote.port指定的端口)
用户名:monitorRole
密码:your password(jmxremote.pwd中设置的密码)
13. 点击“连接”
访问方式
1.Local方式
1、cmd进入dos下,进入到应用程序所在目录,执行语句如下:
java -Dcom.sun.management.jmxremote -jar 程序名.jar
(java -Dcom.sun.management.jmxremote -jar Java2Demo.jar)(测试例子Java2Demo.jar在
C:\Program Files\Java\jdk1.6.0_02\demo\jfc\Java2D\)
还出不来的话直接在dos里jconsole 进程号
2、启动jdk_home\bin目录下的Jconsole.exe就可以看到有一个本地的连接在里面。
点击连接就可以进入相应的监视界面了。
2.JMX方式(远程连接)
1、cmd进入dos下,进入到应用程序所在目录,执行语句如下:
java -Dcom.sun.management.jmxremote.port=8903 -
Dcom.sun.management.jmxremote.ssl=false -
Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=192.168.***.***
2、启动jdk_home\bin目录下的Jconsole.exe点高级。
在JMX URL:中输入语句如下:service:jmx:rmi:///jndi/rmi://192.168.***.***:8903/jmxr mi
点连接就可以进行远程监控了
web应用程序在tomcat中部署JMX(示例:tomcat-6.0.14)
1、启动tomcat\bin目录下的tomcat6w.exe,在JA V A_OPTS里设置如下:
-Dcom.sun.management.jmxremote.port=8903
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=192.168.***.***
注意:不能有空格,不然tomcat不能启动。
2、tomcat启动成功后,就可以在另一台机器上启动jdk_home\bin目录下的Jconsole.exe点高级。
在JMX URL:中输入语句如下:
service:jmx:rmi:///jndi/rmi://192.168.***.***:8903/jmxrmi
点连接就可以进行远程监控了
以上是JMX基本部署,没有涉及到验证方面,如果使用的话,可能会有漏洞,因为SSL和authenticate设置为false的话,那么8903端口就有可能有暴露的危险。
我自己的应用:
1.修改Linux下tomcat的bin目录下的catalina.sh文件
添加
JA V A_OPTS=-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=7080
-Dcom.sun.management.jmxremote
2.修改/etc/hosts文件下的localhost对应的IP(127.0.0.1)地址,改为linux自身的IP如10.0.0.157
3.打开jconsole远程输入10.0.0.157:7080
3.高级
使用一个特殊的URL连接JMX代理。
一般情况使用自己定制的连接器而不是RMI提供的连接器来连接JMX代理,或者是一个使用JDK1.4的实现了JMX和JMX Rmote的应用。
当JConsole成功建立连接,它从连接上的JMX代理处获取信息,并且以下面几个标签页呈现信息:
Eden Space (heap):内存最初从这个线程池分配给大部分对象。
Survivor Space (heap):用于保存在eden space内存池中经过垃圾回收后没有被回收的对象。
Tenured Generation (heap):用于保持已经在survivor space内存池中存在了一段时间的对象。
Permanent Generation (non-heap): 保存虚拟机自己的静态(refective)数据,例如类(class)和方法(method)对象。
Java虚拟机共享这些类数据。
这个区域被分割为只读的和只写的,Code Cache (non-heap):HotSpot Java虚拟机包括一个用于编译和保存本地代码(native code)的内存,叫做“代码缓存区”(code cache)
应用监控
jconsole 可以很方便的监控本机的所有Java 应用和远程应用.
监控本地应用
首先就是启动您要监控的应用,例如我用JDK 1.6 来启动了Tomcat,或者Eclipse 也可以,可以在任务管理器(Ctrl+Alt+Del可以调出来,或者在任务栏点击右键)里看到进程ID,例如我这里是6132。
接着在JDK 安装目录中(<JDK_HOME>/bin/jconsole.exe)启动jconsole.exe (双击或者在cmd 里面敲入jconsole),主界面会提示您建立一个新连接:
可以看到进程ID,选择它,然后点击"连接"。
这些ID 必须都是用JDK 1.6的java.exe 启动的,否则在列表里看不到。
JConsle 能监控内存,线程,类的数目和CPU然后点击各个Tab 可以看到详细的输出,详细的输出包括:
内存: 堆/非堆,峰值,内存的各个部分,例如Perm,Eden 等的大小曲线图.
线程: 峰值,所有线程的列表,堆栈跟踪(哪个对象中的线程)等. 还可以强制执行GC。
类: 峰值,类总数曲线图.
MBean: 一些JVM 参数的详细MBean信息.
监控远程进程
首先需要在运行的应用上启用远程管理,参数如下(简单起见就不加用户验证了):
java -Dcom.sun.management.jmxremote.port=1090 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar ../demo/jfc/Java2D/Java2Demo.jar
然后连接的时候选择远程进程,地址输入应用网址即可(如localhost:1090),当然在别的电脑上(一般是局域网)可以输入那个电脑的IP.
综述: 使用JConsole 可以简单的监控Server 状态,但是本身要占一定的资源,不过JVM 自带的监控,理论上讲应该是占资源很小很小的,可以用它来方便的了解Web 服务器应用进程的状态。
如果要调优应用,还是使用JProfiler 等工具更好一些,当然它们占的资源也更大.
后记:jdk1.6.0\demo\management\MemoryMonitor这里带了个很好的画内存曲线图的例
子... 大家改改就可以实现同时监控多台Server 的内存曲线了....
功能详解架构概览
启动jconsole
JConsole是一个基于JMX的GUI工具,用于连接正在运行的JVM,不过此JVM需要使用可管理的模式启动。
如果要把一个应用以可管理的形式启动,可以在启动是设置com.sun.management.jmxremote。
例如,启动一个可以在本地监控的J2SE的应用Java2Demo ,需输入以下命令:
JDK_HOME/bin/java -Dcom.sun.management.jmxremote -jar JDK_HOME/demo/jfc/Java2D/Java2Demo.jar
JDK_HOME需要是一个含有JDK5.0的目录。
要启动JConsole,运行
JDK_HOME/bin/jconsole
一个用于连接的对话框将会打开。
对话框的Local标签列出了所有本地正在运行的JVM,还包含进程的ID等信息。
Figure 2: Local Tab.
JConsole可以以三种方式连接正在运行的JVM:
Local:使用JConsole连接一个正在本地系统运行的JVM,并且执行程序的和运行JConsole 的需要是同一个用户。
JConsole使用文件系统的授权通过RMI连接器连接到平台的MBean 服务器上。
这种从本地连接的监控能力只有Sun的JDK具有
Remote:使用下面的URL通过RMI连接器连接到一个JMX代理:
service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi
hostName填入主机名称,portNum为JMX代理启动时指定的端口。
JConsole为建立连接,需要在环境变量中设置mx.remote.credentials来指定用户名和密码从而进行授权。
Advanced:使用一个特殊的URL连接JMX代理。
一般情况使用自己定制的连接器而不是RMI提供的连接器来连接JMX代理,或者是一个使用JDK1.4的实现了JMX和JMX Rmote 的应用。
当JConsole成功建立连接,它从连接上的JMX代理处获取信息,并且以下面几个标签页呈现信息。
Summary tab. 监控JVM和一些监控变量的信息。
Memory tab. 内存使用信息
Threads tab. 线程使用信息
Classes tab. 类调用信息
VM tab. JVM的信息
MBeans tab.所有MBeans的信息
MBeans tab展示了所有以一般形式注册到JVM上的MBeans。
MBeans tab允许你获取所有的平台信息,包括那些不能从其他标签页获取到的信息。
注意,其他标签页上的一些信息也在MBeans这里显示。
另外,你可以使用MBeans标签管理你自己的应用的MBeans
使用MBeans Tab监控和管理MBean
注册到JMX代理的平台或者应用的MBeans,可以通过MBeans标签获取。
例如,内存的MBeans如下面定义:
public interface MemoryMXBean { public MemoryUsage getHeapMemoryUsage(); public MemoryUsage getNonHeapMemoryUsage(); public int getObjectPendingFinalizationCount(); public boolean isVerbose(); public void setVerbose(boolean value); public void gc(); }内存的MBean包括四个属性:
HeapMemoryUsage. 用于描述当前堆内存使用情况的只读属性NonHeapMemoryUsage. 用于描述当前的非堆内存的使用情况的只读属性ObjectPendingFinalizationCount.用于描述有多少对象被挂起以便回收。
Verbose.用于动态设置GC是否跟着详细的堆栈信息,为一个布尔变量
内存的MBean支持一个操作——GC,此操作可以发送进行实时的垃圾回收请求。
Figure 3: MBeans Tab.
左边的树形结构以名字的方式展示了所有MBeans的列表。
一个MBean对象的名字由一个域的名字和一串关键字属性组成。
例如,JVM的平台的MBeans是在“ng”域下的一组,而日志的MBeans则在"java.util.logging"域下。
MBean对象的名字在javax.management.ObjectName 规范中定义。
当你在树中选中一个MBean,属性,方法,或者通知等一些信息会再右边显示出来。
如果属性是可写的(属性被标志为蓝色),你可以进行设置。
你可以操作在Operations tab中列出的操作。
你也可以看到由MBean发送出来的通知:默认情况,如果你不订阅通知的话,JConsole不会收到MBean发生过来的通知。
你可以点击"Subscribe"(订阅)按钮来堆通知进行
定义,而使用"Unsubscribe"按钮来取消订阅
Figure 4: MBeans Notification.
监控内存
内存标签页通过读取内存系统、内存池、垃圾回收的MBean来获取对内存消耗、内存池、垃圾回收的情况的统计。
图:
上图展示了内存随时间变化的使用情况。
有对堆的、非堆的以及特殊内存池的统计。
内存池信息是否能被获取,取决与使用的Java虚拟机。
下图列表展示了HotSpot虚拟机的内存池情况。
Eden Space (heap):内存最初从这个线程池分配给大部分对象。
Survivor Space (heap):用于保存在eden space内存池中经过垃圾回收后没有被回收的对象。
Tenured Generation (heap):用于保持已经在survivor space内存池中存在了一段时间的对象。
Permanent Generation (non-heap): 保存虚拟机自己的静态(refective)数据,例如类(class)和方法(method)对象。
Java虚拟机共享这些类数据。
这个区域被分割为只读的和只写的,Code Cache (non-heap):HotSpot Java虚拟机包括一个用于编译和保存本地代码(native code)的内存,叫做“代码缓存区”(code cache)
详细信息区域给出一些当前线程的信息:
Used:已使用:当前的内存使用量。
使用的内存包括所有对象(能被获取和不能被获取的)所占用的内存。
Committed:分配量:Java虚拟机保证能够获取到的内存量。
分配内存(committedmemory)的量可能随时间改变。
Java虚拟机可能释放部分这里的内存给系统,相应的分配的内存这时可能少于初始化时分配的给它的量。
分配量总数大于或等于已使用的内存量。
Max :内存管理系统可以使用的最大内存量。
这个值可以被改变或者不做设定。
如果JVM试图增加使用的内存到大于分配量(committedmemory)的情况,内存分配可能失败,即便想使用的内存量小于或者等于最大值(如:系统虚拟内存比较低时)
Usage Threshold The usage threshold of a memory pool. This field will only beshown if the memory pool supports usage threshold.
GC time :垃圾回收使用的总时间和调用垃圾回收的次数。
它可能有好几行,每行代表JVM 使用的垃圾回收算法。
右下角的棒状图表显示了被JVM的内存池消耗的内存。
如果内存使用超过usage threshold,则棒会变红。
usagethreshold是用于支持内存检查的Memory Pool MBean的一个属性。
MemoryPoolMXBean定义了一系列方法用于检查内存。
public interface MemoryPoolMXBean {
....
// Usage threshold
public long getUsageThreshold();
public void setUsageThreshold(long threshold);
public boolean isUsageThresholdExceeded();
public boolean isUsageThresholdSupported();
// Collection usage threshold
public long getCollectionUsageThreshold();
public void setCollectionUsageThreshold(long threshold);
public boolean isCollectionUsageThresholdSupported();
public boolean isCollectionUsageThresholdExceeded();
}
每种内存池可能有两种内存初始话支持:usage threshold和collection usage threshold 特殊的内存池可能两种都不支持。
Usage Threshold
usage threshold是内存池中一个可管理的属性。
它使用低负荷的内存监控。
设置usage threshold为正值则usage threshold检查内存池。
设置usage threshold为零,则关闭检查。
默认值由JVM设置。
JVM一般让usage threshold在最合适的时候检查内存,典型的在GC的过程中和某些分配内存的时候。
如果JVM发现当前的内存使用超过了usage threshold,它将会把UsageThresholdExceeded属性设置为true
有些内存池可能不支持usage threshold。
你可以使用UsageThresholdSupported属性来判断一个内存池是否支持usage threshold。
例如,一个比较完善(generational garbage collector)的垃圾回收器(如HotSpot的虚拟机),most of the objects are allocated in the young generation,从eden内存池中产生。
eden pool被设计成可以被装满;再eden pool中执行垃圾回收将会释放他
Collection Usage Threshold
Collection usage threshold是可进行垃圾回收的内存池的一个可配置属性。
JVM堆一个内存池进行垃圾回收以后,此内存池中的一些内存仍然被那些没有被回收的对象占用。
collection usage threshold仅允许你在垃圾回收后对内存进行检查。
如果JVM发现可用内存超出collection usage threshold,它将会设置CollectionUsageThresholdExceeded属性为true。
你可以使用CollectionUsageThresholdSupported属性来控制内存池释放支持collection usage threshold.
usage threshold 和collection usage threshold是MBean标签中的一组。
例如,在左边的树形结构中选择TenuredGen,设置tenured generation memory pool的usage threshold为6m。
如下图所示
Figure 6: Setting Usage Threshold.
当TenuredGen memory pool的内存使用超过6MBytes时,代表TenuredGen memory
pool的柱状图将会呈现红色来代表使用的内存超过了usage threshold。
代表堆内存的柱状图也将变为红色。
你可以选择柱状图或者在图表中指定内存池来查看某个指定内存池的信息。
如果把鼠标房子柱状图上,将会显示出内存池的名字
Figure 7: Low Memory.
开启/关闭虚拟机的详细跟踪
如上所述,内存系统的MBean定义了一个叫做V erbose布尔变量,让你能动态的打开或关闭详细的GC跟踪。
详细的GC跟踪,将会在JVM启动时显示。
默认的HotSpot的GC 详细输出为stdout.
Figure 8: Setting Verbose GC.
死锁检查
线程标签页提供关于应用的线程运行信息
Figure 9: Threads Tab.
左下角列出了所以正在运行的线程。
如果你在过滤器中输入一个字符,线程列表将仅显示线程名字包含你输入字符的线程。
通过点击某个线程,你可以获取这个线程的相关信息。
线程的MBean标签提供了一些Thread标签没有提供有用的操作。
findMonitorDeadlockedThreads. 如果发生线程死锁,可以通过这个检查出来。
操作返回一组死锁的线程ID
getThreadInfo. 返回线程的信息。
包括线程的名称、堆栈信息,导致当前线程阻塞的锁,如果有的话,还返回哪儿线程持有这个锁,和这个线程信息的统计。
getThreadCpuTime.返回指定线程消耗的CPU时间。
为使用上面这些属性,可以到MBeans标签下,在MBeans树上选择Threading MBean。
它
列出了当前监控的JVM所有属性的操作。
Figure 10: MBeans Tab Threading.
为检查你的应用是否进入死锁(例如,你的应用挂起),你可以使用
findMonitorDeadlockedThreads操作。
Figure 11: Find Deadlocked Threads.
一旦你选择了findMonitorDeadlockedThreads按钮,将会有一个弹出窗口显示结果。
在上面例子中,JConsole连接了一个存在3个死锁线程的示例应用SampleTest。
如上所示,检查出ID为12,10和11的线程死锁。
想查询更多的线程信息,可以使用getThreadInfo操作。
线程的MBean支持getThreadInfo操作的四种形式,
对一个给定的线程ID,给出最深的堆栈情况
堆一系列的线程ID,给出最深的堆栈情况
Of a given thread ID with no stack trace.
Of an array of thread IDs with no stack trace.
对应死锁情况,你一般会比较关系堆栈情况。
你可以在getThreadInfo操作的第一个参数中
输入死锁的线程ID和你想跟踪的堆栈深度。
Figure 12: ThreadInfo for Thread ID = 12.
双击stackTrace属性的值域将会显示一个复合对话框,你可以在堆栈中来回查看。
图13,14
显示了死锁线程-1的复合对话框中的第一层堆栈和第二层堆栈。
Figure 13: Top Frame of the Stack Trace of DeadlockedThread-1.
Figure 14: Second Frame of the Stack Trace of DeadlockedThread-1.
线程标签页提供了一个友好的界面供查看线程的堆栈。
你可以找到死锁线程的名字,使用getThreadInfo 查找线程信息。
然后又可以使用线程标签页来分析死锁。
控制日志等级
Logging MBean定义了LoggerNames属性,用于描述日志名称。
为找到你的应用的日志,可以选择在MBeans树中java.util.logging 下的Logging MBean,双击LoggerNames属性
Figure 15: List of All Logger Names.
Logging MBean也支持三种操作:
getParentLoggerName. 返回指定logger的父logger
getLoggerLevel. 返回指定logger的日志等级
setLoggerLevel.设置指定logger到一个新的等级
所有三个操作都把日志名称作为第一个参数。
Figure 16: Setting Log Level.
获取操作系统资源信息-Sun平台下的扩展
JDK5.0扩展了操作系统的MBean,以此可以获取一下系统资源的信息,如:处理的CPU
总共的和空闲的物理内存
可获得的虚拟内存。
(即保证可以分配给运行的进程的虚拟内存)
总共的和空闲的交换区
打开的文件总数(只能在Unix下使用)
当打开MBeans标签下的Operating System MBean,你可以看到平台可以执行的所有属性和操作。
你可以监控任何一个属性随时间的变化——如,CPU时间-双击属性的值域部分。
Figure 17: MBeans Tab OS.
除此之外,VM标签和Summary标签提供了操作系统资源的一些信息
管理应用的MBean
被监控的SampleTest应用有它自己的Hello MBean:
com.sun.example:type=Hello
如果CacheSize 属性发生改变,Hello MBean将会发送一个通知。
你可以和管理平台的MBeans一样使用MBeans标签页来管理你的应用的MBean。
例如,当CacheSize 属性变化的时候你想监控。
你首先可以在Notification标签页中订阅。
如果你改变CacheSize,你可以
看到一个通知被发送。
Figure 18: Notifications.
相关信息
Monitoring and Management for the Java Platform
/j2se/1.5.0/docs/guide/management/
Monitoring and Management Tools
/j2se/1.5.0/docs/tooldocs/index.html#manage
如果觉得这个功能还不够强大,那么给大家推荐另外一款非常出名的软件:Jprofiler。
它是一款java的性能检测工具,可以查看当前应用的对象、对象引用、内存、CPU使用情况、线程、线程运行情况(阻塞、等待等),同时可以查找应用内存使用得热点,即:哪个对象
占用的内存比较多。