Quantcast
Channel: CodeSection,代码区,Linux操作系统:Ubuntu_Centos_Debian - CodeSec
Viewing all articles
Browse latest Browse all 11063

Zabbix使用自动发现功能监控服务器各JVM进程状态

$
0
0

前言

==========

为什么需要做服务器jvm自动发现的监控呢?这个事情主要有两点原因:

1.zabbix默认监控jvm状态是使用jmx中转进行监控的,监控效率比较低下

2.zabbix使用jmx监控jvm的时候由于一个主机上的键值不能重复,也就导致了一台主机上只能监控一个jvm实例

以上两点原因导致zabbix通过jmx监控jvm的实现不是很理想,加上最近老大要求收集服务器上面跑的所有java应用的信息,于是自己琢磨了下,还是自己动手,丰衣足食。利用了周末的时间,通过使用shell脚本+java工具jstat+zabbix实现监控主机上多jvm实例的功能。

第一章:概念的理解

首先,既然要监控jvm状态,那就必须要了解jvm里面的信息,楼主通过搜索资料加自动脑补,把网上的资料取其精华,去其糟粕,整理了一下。JVM中的内存分类分为堆内存和非堆内存,堆内存是给实际应用使用的,非堆内存是给jvm容器使用的。我们主要关心的是堆内存这块。在堆内存里面,给内存分为如下几块:

1.Young代(年轻代)

2.Old代(老年代)

3.Perm代(永久代)(关于这一点,在JDK7和JDK8中情况不一样,将在后面进行分析)

其中,年轻代里面又分成了三块,如下:

1.Eden代(伊甸园代)

2.survivor0代(0号幸存区)

3.survivor1代(1号幸存区)

至于更详细的关于JVM堆内存的信息,各位可以自行百度或者google,我这里就不赘述了,毕竟我也是个半桶水,自己找了点资料外加脑补到的一些东西,不敢在关公门前耍大刀了。

当然,还得科普一个东西,那就是GC,所谓的GC就是JVM在运行的时候会有一个垃圾回收机制,这个垃圾回收机制是什么情况呢?就是在程序运行的时候会产生很多已经不使用的空间,但还是被占用了的情况,这样会造成很多不必要的浪费,于是JVM就有一个垃圾回收机制,针对程序中已经不使用的内存资源,会进行回收释放,这个过程就叫做GC。当然,关于GC还有很多内容我这里也没有详述,理由同上条。各位看官只需要知道GC是JVM监控里面的一个很重要的参数就行了。

第一章,关于JVM中概念的理解结束了,预知后事如何,请听下回分解。

第二章:JAVA工具的选用

java工具有很多,关于jvm监控的工具主要有如下几个:

+ jstat

+ jmap

+ jstack

其中jmap --heap pid可以抓出挺多的关于某个jvm的运行参数,但是老大提醒我最好不要使用jmap进行jvm监控,具体没有说明原因。于是本着打破砂锅问到底的精神,我又去搜了一把,发现了如下内容:

jmap最主要的危险操作是下面这三种:

1. jmap -dump

这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用。

2. jmap -permstat

这个命令执行,JVM会去统计perm区的状况,这整个过程也会比较的耗时,并且同样也会暂停应用。

3. jmap -histo:live

这个命令执行,JVM会先触发gc,然后再统计信息。

上面的这三个操作都将对应用的执行产生影响,所以建议如果不是很有必要的话,不要去执行。

所以,从上面三点来看,jmap命令对jvm状态影响还是比较大的,而且执行jmap --heap的时间也比较长,效率较低,予以排除。

接下来是jstack,这个命令可以深入到JVM里面对JVM运行问题进行排查,据说还可以统计JVM里面的线程数量。但是这个命令执行效率也比较低,被排除掉了。

于是剩下的只有一个jstat命令了。下面来详细的讲解该命令的使用了,咳咳,各位快点打起点精神来,这可是重头戏来了。

首先,列出jstat命令的一些使用案例吧:

============================================

1.jstat -gc pid

可以显示gc的信息,查看gc的次数,及时间。

其中最后五项,分别是young gc的次数,young gc的时间,full gc的次数,full gc的时间,gc的总时间。

S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT

9792.0 10048.0 0.0 5143.2 242048.0 220095.4 323200.0 211509.3 186368.0 114451.6 317 4.850 4 0.971 5.821

S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT

1024.0 1024.0 0.0 320.0 11776.0 11604.6 260608.0 149759.6 39344.0 38142.6 4528.0 4303.1 5473 24.010 2 0.128 24.138

2.jstat -gccapacity pid

可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小,

如 PGCMN显示的是最小perm的内存使用量,PGCMX显示的是perm的内存最大使用量,

PGC是当前新生成的perm内存占用量,PC是但前perm内存占用量。

其他的可以根据这个类推, OC是old内纯的占用量。

NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC PGCMN PGCMX PGC PC YGC FGC

87360.0 262144.0 262144.0 9792.0 10048.0 242048.0 174784.0 786432.0 323200.0 323200.0 131072.0 262144.0 186368.0 186368.0 317 4

NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC

1536.0 174592.0 13312.0 512.0 512.0 11776.0 260608.0 349696.0 260608.0 260608.0 0.0 1083392.0 39344.0 0.0 1048576.0 4528.0 5474 2

3.jstat -gcutil pid

统计gc信息统计。

S0 S1 E O P YGC YGCT FGC FGCT GCT

0.00 51.19 83.29 65.44 61.41 317 4.850 4 0.971 5.821

S0 S1 E O M CCS YGC YGCT FGC FGCT GCT

68.75 0.00 46.74 57.47 96.95 95.03 5474 24.014 2 0.128 24.143

4.jstat -gcnew pid

年轻代对象的信息。

S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT

9792.0 10048.0 0.0 5143.2 3 15 9792.0 242048.0 198653.2 317 4.850

S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT

512.0 512.0 352.0 0.0 15 15 512.0 11776.0 8446.4 5474 24.014

5.jstat -gcnewcapacity pid

年轻代对象的信息及其占用量。

NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC

87360.0 262144.0 262144.0 87360.0 9792.0 87360.0 10048.0 262016.0 242048.0 317 4

NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC

1536.0 174592.0 13312.0 57856.0 512.0 57856.0 512.0 173568.0 11776.0 5475 2

6.jstat -gcold pid

old代对象的信息。

PC PU OC OU YGC FGC FGCT GCT

186368.0 114451.6 323200.0 211509.3 317 4 0.971 5.821

MC MU CCSC CCSU OC OU YGC FGC FGCT GCT

39344.0 38142.6 4528.0 4303.1 260608.0 149783.6 5475 2 0.128 24.148

7.jstat -gcoldcapacity pid

old代对象的信息及其占用量。

OGCMN OGCMX OGC OC YGC FGC FGCT GCT

174784.0 786432.0 323200.0 323200.0 317 4 0.971 5.821

OGCMN OGCMX OGC OC YGC FGC FGCT GCT

260608.0 349696.0 260608.0 260608.0 5475 2 0.128 24.148

8.jstat -gcpermcapacity pid

perm对象的信息及其占用量。

PGCMN PGCMX PGC PC YGC FGC FGCT GCT

131072.0 262144.0 186368.0 186368.0 317 4 0.971 5.821

没有

9.jstat -class pid

显示加载class的数量,及所占空间等信息。

Loaded Bytes Unloaded Bytes Time

25315 45671.7 5976 7754.1 15.19

Loaded Bytes Unloaded Bytes Time

6472 11893.0 0 0.0 5.97

10.jstat -compiler pid

显示VM实时编译的数量等信息。

Compiled Failed Invalid Time FailedType FailedMethod

4219 3 0 63.36 1 org/aspectj/weaver/ResolvedType addAndRecurse

Compiled Failed Invalid Time FailedType FailedMethod

11364 1 0 107.53 1 sun/nio/cs/UTF_8$Decoder decode

11.stat -printcompilation pid

当前VM执行的信息。

Compiled Size Type Method

4219 2232 1 net/spy/memcached/protocol/ascii/BaseGetOpImpl initialize

Compiled Size Type Method

11364 212 1 com/alibaba/rocketmq/client/impl/consumer/RebalanceService run

==================================================

可以看出上面我列出的命令执行结果为什么有两行呢,这是因为是用不同的jdk版本执行的。

上面是JDK7执行结果,下面是JDK8执行结果,这两个版本之间输出的结果是有差距的,下面,就来分析为什么会产生这种差异。

JDK7和JDK8中JVM堆内存划分差异

如果记性好的童鞋们应该还能记得我上面在介绍JVM堆内存分类的时候括号里写的那个东东吧,没错,就是这个东西导致的。在JDK7中的Perm代(永久代)在JDK8中被废除了,取而代之的是Metadata代(元数据代),据说这个元数据代相对于永久代进行了优化,如果不设置最大值的话,默认会按需增长, 不会造成像Perm代中内存占满后会爆出内存溢出的错误,元数据代也可以设置最大值,这样的话,当内存区域被消耗完的时候将会和Perm代一样爆出内存溢出的错误。(PS:原谅我的班门弄斧,只能解释到这一个层面了。)

好了,解释清楚了JDK7和JDK8的差异以后,接下来我们来解释jstat抓到的这些参数了。

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 jstat命令获取参数解析

======================================================================================

* S0C 年轻代中第一个survivor(幸存区)的容量 (字节)jstat -gcnew $pid|tail -1|awk '{print $1*1024}'

* S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节)jstat -gcnew $pid|tail -1|awk '{print $3*1024}'

* S0 年轻代中第一个survivor(幸存区)已使用的占当前容量百分比jstat -gcutil $pid|tail -1|awk '{print $1}'

* S0CMX 年轻代中第一个survivor(幸存区)的最大容量 (字节)jstat -gcnewcapacity $pid|tail -1|awk '{print $4*1024}'

*

* S1C 年轻代中第二个survivor(幸存区)的容量 (字节)jstat -gcnew $pid|tail -1|awk '{print $2*1024}'


Viewing all articles
Browse latest Browse all 11063

Trending Articles