点击上方“IT那活儿”公众号,关注后了解更多内容,不管IT什么活儿,干就完了!!!

我们在日常运维工作,往往需要对基于java开发的组件的重要性能指标进行实时监测与告警,而实现监测手段用的最多的还是基于jmx(Java Management Extensions)来实现。
JMX是管理Java的一种扩展,用于定义了应用程序以及网络管理和监控的体系结构、设计模式、应用程序接口以及服务,通过jmx这种机制可以方便的管理、监控正在运行中的Java程序,常用于管理线程,内存,日志Level,服务重启,系统环境等。
常用部署使用jmx 监测主要是分为如下几种方式:
1. jvm部署代理agent(主动方式):
JVM 启动时指定参数,通过 javaagent 的形式运行监测程序依赖包,因为监测依赖包跟jvm本身是部署在一起,是通过在进程内读取jvm运行时的性能数据,实时将metrics 性能数据暴露出来,本质上在本机上利用jmx协议监测实现,如jmx_exporter/apm(pinpoint/skywalking) 自研agent程序等
2. 开启jmx远程访问(被动方式):
JVM 启动时指定参数,暴露 JMX 的 RMI 接口,第三方工具调用 RMI 获取 JVM 运行时状态数据,常用jconsole/jvisualvm/zabbix等
3. 在自己程序里面自行实现jmx 自带MXBean管理接口,读取性能指标信息。
不同客户环境不一样,所采取方式都有所不同,本文以tomcat 8.5.x+jdk1.8监测为例,实践利用开启jmx远程访问的方式, 获取核心指标,检验核心指标告警可行性。
1. 核心指标
梳理影响业务性能的部份关键指标,用于规则告警,实时发现应用的性能问题。

2. 测试程序
编写异常测试场景程序,检验利用jmx方式是否能扑获到异常。
3. 开启jmx远程访问
打开tomcat/bin/catalina.sh文件,在现有的shell 文件里面的shift与touch "$CATALINA_OUT"的中间,新增以下内容:
重启tomcat 服务,利用ps -ef|grep tomcat 检查参数是否生效。
4. 异常场景检测
1)下载cmdline-jmxclient-0.10.3.jar工具,用于抓取jmx的mbean信息。
http://crawler.archive.org/cmdline-jmxclient/cmdline-jmxclient-0.10.3.jar
2)使用方法
java -jar cmdline-jmxclient-0.10.3.jar --help
Usage: java -jar cmdline-jmxclient.jar USER:PASS HOST:PORT [BEAN] [COMMAND]
说明:如果jmx未开启用户名与密码访问,需要用- 进行替代,而帮助里面。
3)查看服务器所有Mbeans的信息
java -jar cmdline-jmxclient-0.10.3.jar - 127.0.0.1:10990
mbeans有很多,我们通常重点关注如下bean即可。

4)场景一: 线程池满

告警规则:ThreadCount=maxThreads 代表线程池已满。
5)场景二:堆内存使用率

告警规则:
l堆内存使用/堆内存最大分配>0.95 需要告警;
l非堆内存使用/非堆内存最大分配>0.95 需要告警;
l元空间使用/元空间最大分配>0.95 需要告警。
6)场景三:死锁线程
运行造成死锁程序案例,造成多个线程之间互相等待,形成了死锁现象。

注意:cmdline-jmxclient提供操作获取线程信息的方法,按提供的命令参数,在实践过程老是报错,网上及官网也没有搜索到解决方案(https://webarchive.jira.com/browse/HER-1630),目前只能通过编写代码来实现。
long[] ids = threadMXBean.getAllThreadIds();
for (long id : ids) {
ThreadInfo threadInfo = threadMXBean.getThreadInfo(id);
System.out.println(threadInfo.getBlockedCount());
System.out.println(threadInfo.getBlockedTime());
System.out.println(threadInfo.getWaitedCount());
System.out.println(threadInfo.getWaitedTime());
}
死锁线程数量:3
线程:Thread-40正在等待,线程:Thread-8持有的锁;
线程:Thread-8正在等待,线程:Thread-7持有的锁;
线程:Thread-7正在等待,线程:Thread-8持有的锁。
告警规则:
l死锁线程数量>0 需要告警。
7)场景四:内存溢出
将tomcat jvm 堆大小调小并且设置内存溢出时自动生成headdump文件,设置成 -Xms10m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError ,运行造批量生成对像测试程序。



存在现象:
ljmx 没有一个专门指标来说明如获取是否产生了oom 文件;
l会存在进程oom 情况下,但堆内存使用比率并没有占满的现象,所以内存溢出不能完全依赖这个条件。
告警规则:
l扫描日志关键字:OutOfMemoryError ,存在就告警;
l当监测到full gc 次数在短时间内有明显增长时,需要告警。
8)jndi连接池满场景

告警规则:
ljndi活动连接数=jndi最大连接数需告警。
9)其它场景

告警规则:
ltomcat进程CPU使用率需要根据业务实际情况配置对应告警阀值;
l打开文件数句柄/最大打开文件数句柄>0.95 需要告警。
小结:利用jmx 监测并不能完全解决日常监测场景所面对的问题,需结合日志关键字提升异常监测的准确性。

本文作者:暨景书
本文来源:IT那活儿(上海新炬王翦团队)





