JMX与中间件
罗扬
【摘要】
本文以tomcat为例子,介绍如何使用jmx获取tomcat的配置信息和运行信息。
【正文】
在百度上jmx的解释为:JMX(Java
Management Extensions,即Java管理扩展)在Java编程语言中定义了应用程序以及网络管理和监控的体系结构、设计模式、应用程序接口以及服务。通常使用JMX来监控系统的运行状态或管理系统的某些方面,比如清空缓存、重新加载配置文件等。
简单来说,jmx为java中的一套框架,一套规范,和JPA,JMS是一样的,它是为了把监控和管理系统等放在一起,对外提供统一的接口。那么只要代码实现了jmx这套规范,那么我们在外部就可以用一种统一的方式调用这些接口,获取到内部的信息或管理它,注意,其前提是实现了jmx规范。
而在市面上常用的java中间件大部分都是基于jmx架构开发的,比如jboss,weblogic,tomcat,中创等,本文会以tomcat为例子,介绍如何使用jmx获取到tomcat的配置信息和性能信息。
Jconsole (Java
Monitoring and Management Console),一种基于JMX的可视化监视、管理工具。是一个内置的java性能分析器,在占用极低系统资源下,对jvm中的内存,线程和类等进行监控,可以监控本地jvm进程,也可远程jvm进行监控。
在按照jdk后,在jdk/bin目录下可以找到它。
Jconsole会搜索本地jvm进程,可以远程连接jvm进程。
连接jvm进程
Jconsole基本功能:
概述(图表展示实时的堆内存,线程等信息),
内存(jvm内存信息—堆内存,非堆内存,内存池信息等),
线程(图表展示线程池的信息),
类(类总数信息),
vm概要(文字展示概述信息),
MBean(最详细的信息,管理各类对象,这里可以找到前面所有的信息)
Jconsole工具是一个图形化工具,在没有图形化的服务器上一般无法使用jconsole连接jmx,所以我们可以使用远程连接的方式连接tomcat的jvm进程。
远程的前提是tomcat需要开放出jmx的端口出来允许我们连接,我们需要修改tomcat的配置文件来开启这个jmx端口。
在tomcat的bin目录下catalina.sh文件中,添加下面这段配置:
hostname:配置jmx监听地址,填入本地ip,也可填入127.0.0.1
port:配置jmx监听端口
ssl:取消ssl认证
authenticate:取消登陆验证,也可配置登陆验证
配置完成后,重启tomcat生效配置。
Catalina:包含tomcat的大部分配置信息,及运行信息
User:tomcat的用户配置
其余的为jvm本身的信息,比如内存池等信息
实例信息:
属于http协议的8080端口的线程池信息:
Jmx为java规范,使用java可以原生的远程连接jmx端口,取得与jconsole类似的能力,这种方式需要使用java开发,且并不是脚本化的操作,本文不详细描述。
使用方式:java -jar
cmdline-jmxclient.jar USER:PASS HOST:PORT [BEAN] [COMMAND]
用命令的方式向cmdline-jmxclient-0.10.3.jar传入账号密码(即jconsole工具远程连接是所需输入的账号密码,也是在tomcat配置jmx中设置登陆验证的账号密码),如果为空则传入“-”,传入需要远程的ip和端口(即jconsole工具远程连接输入的ip+端口),传入需要获取的对象名称与命令(后续介绍如何查看)。
原理:传入命令,底层与4.1原理相同,使用java调用jmx获取信息。
如何下载文件:百度即可
举例:
获取实例的信息
使用cmdline-jmxclient-0.10.3.jar需要ip端口等基本信息外,我们还需要知道我们需要获取哪个对象的属性,或者说我们需要获取哪个MBean的属性。
首先,我们选中MBean,其右边会显示其对象名称:
在找到这个对象下所需要获取的属性名:
组合出命令为:java -jar
cmdline-jmxclient.jar USER:PASS HOST:PORT Catalina:type=ThreadPool,name=\"ajp-nio-8009\"
selectorTimeout (注意,””需要转义)
在遇到这个MBean下可能会有多个对象的情况下,比如tomcat中开放出来的ajp协议和http协议的端口不固定时,我么可以使用*代表其名字:
java -jar
cmdline-jmxclient.jar USER:PASS HOST:PORT Catalina:type=ThreadPool,name=* selectorTimeout
会返回匹配到这个对象名的所有对象名(若只匹配到一个,则直接返回这个对象的selectorTimeout属性)
综合上面的jmx使用方式,我们可以使用cmdline-jmxclient-0.10.3.jar工具完成一个对tomcat的监控脚本:
#!/bin/bash
getmemorykey(){
arr=($*)
echo
${arr[-8]}
echo
${arr[-7]}
echo
${arr[-6]}
echo
${arr[-5]}
echo
${arr[-4]}
echo
${arr[-3]}
echo
${arr[-2]}
echo
${arr[-1]}
}
getlastkey(){
OLD_IFS="$IFS"
IFS=":"
arr=($*)
IFS="$OLD_IFS"
echo
${arr[-1]}
}
ip="192.168.169.34"(主机ip,有时候tomcat可以配置成远程端口不外放,只在本机开,这样的话这个ip要改成localhost或者127.0.0.1)
port="12346"(jmx端口)
path_url="java -jar
/root/cmdline-jmxclient-0.10.3.jar - $ip:$port"
echo "HeapMemory:"$(getmemorykey
`$path_url java.lang:type=Memory HeapMemoryUsage 2>&1` 2>&1)
echo
"NonHeapMemory:"$(getmemorykey `$path_url java.lang:type=Memory
NonHeapMemoryUsage 2>&1` 2>&1)
echo "========="
echo "PermGen:"$(getmemorykey
`$path_url java.lang:type=MemoryPool,name="Perm Gen" Usage
2>&1` 2>&1)
echo "PSPermGen:"$(getmemorykey
`$path_url java.lang:type=MemoryPool,name="PS Perm Gen" Usage
2>&1` 2>&1)
echo "Metaspace:"$(getmemorykey
`$path_url java.lang:type=MemoryPool,name="Metaspace" Usage
2>&1` 2>&1)
echo "========="
threadpool=`$path_url
Catalina:type=ThreadPool,name="*" 2>&1`
poolname=(${threadpool// / })
for var in ${poolname[@]}
do
connc=$(echo
`$path_url $var connectionCount 2>&1` | awk '{print $6}')
curr=$(echo
`$path_url $var currentThreadCount 2>&1` | awk '{print $6}')
echo
$var
echo
"connectNum:"$connc
echo
"currentThreadNum:"$curr
echo
"--------"
done
webapp=`$path_url
Catalina:j2eeType=WebModule,name=*,J2EEApplication=*,J2EEServer=* stateName
2>&1`
len=`echo "$webapp" | wc -l`
echo "========="
if [[ "$len" != "1" ]]
then
applist=($webapp)
for
x in ${applist[@]}
do
echo
$(getlastkey `$path_url $x baseName 2>&1`
2>&1)":"$(getlastkey `$path_url $x stateName 2>&1`
2>&1)
done
else
echo
$(getlastkey `$path_url
Catalina:j2eeType=WebModule,name=*,J2EEApplication=*,J2EEServer=* baseName
2>&1` 2>&1)":"$(getlastkey `$path_url
Catalina:j2eeType=WebModule,name=*,J2EEApplication=*,J2EEServer=* stateName
2>&1` 2>&1)
fi
输出数据示例:
(备注:max:最大分配(-1则为无限,无法计算使用率),used:使用,committed:已提交 适用于:堆内存HeapMemory,非堆内存NonHeapMemory,持久堆)
HeapMemory:committed: 58720256 init:
62914560 max: 883949568 used: 34655600
NonHeapMemory:committed: 46399488 init:
2555904 max: -1 used: 44364768
=========
(备注:这里为持久堆情况,java低版本持久堆名称为PermGen,有一些tomcat发现名称也可能为PSPermGen,高版本java废除PermGen,改名为元空间Metaspace,所以需要判断,只有一个是有用的)
PermGen:org.archive.jmx.Client
java.lang:name=Perm Gen,type=MemoryPool is not a registered bean
PSPermGen:java.lang:name=PS Perm
Gen,type=MemoryPool is not a registered bean
Metaspace:committed: 30408704 init: 0 max:
-1 used: 29019976
=========
(线程池情况,一般存在多个线程池,例如:ajp-nio-8009为线程池名称)
Catalina:name="ajp-nio-8009",type=ThreadPool
connectNum:1(当前连接数)
currentThreadNum:10(当前线程数)
--------
Catalina:name="http-nio-8080",type=ThreadPool
connectNum:1
currentThreadNum:10
=========
(应用状态: 应用名:状态)
examples:STARTED
docs:STARTED
ROOT:STARTED
manager:STARTED
host-manager:STARTED
Last login: Fri Mar 1 12:26:48 CST 2019
我们使用jmx的方式远程连接(如果有网络策略的限制,可以在本地远程连接jmx端口)jvm进程,市面上主流的中间件weblogic,tomcat,jboss,中创都是按照jmx规范开发的,我们可以使用jmx的方式对他们进行配置的获取和性能信息的获取。当然需要这些中间件开启jmx相关的配置,在使用jconsole连接到目标中间件的jvm进程后,除了jvm的基础信息(内存池,java版本,系统版本,系统资源信息等),还会看到该中间件开发给jmx的信息,比如其架构信息,jdbc,线程池等等,我们通过结合jconsole(查看MBean)和cmdline-jmxclient-0.10.3.jar(脚本调用)对中间件进行配置的获取和性能信息的监控。