java gc 监控_JAVA网站full GC监控脚本

我们知道,用JAVA语言写的网站,都会有GC的机制,其中堆的大小,就是新生代空余内存及老年代的空余内存之和。java程序在运行的时候,他会不断把新生代里无法gc掉的对象丢到老年代里面,但是老年代的内存也是一个固定值的,当新生代的对象丢到老年代后,老年代的空余内存会不断缩小,也许大家会问,老年代不是也有GC么,他full gc后,老年代丢弃不用的对象后,使用内存不就是会减少了吗? 说的很对,但是,full gc中,也会有gc不掉的对象,新生代丢给他10个,老年代gc掉8个,那么还剩下两个,无限循环下去,总有一天,老年代会满的。

当老年代内存占满后。Java就会不断的执行full gc, full gc会导致应用暂停,直接就导致网站打不开了,那么我们如何去监控它呢。让他的老年代的内存,达到总内存的80%之后。就发出告警。好通知 sa进行查看及清理。

下面有两种方法。

一,通过jstat查看gc状态

#jstat -gc 12580 1000 10000 如下图

96a0f43ac732bbf7e34c403718597bb6.png

这个图里面 133312000  就是年老代所有的内存,即OC列, OU列就是年老代目前所占用的内存,我们看到,每 YGC 一次,年老代的内存就会增加,

当然,我们不可能一直盯着这个界面,那么,下面我们就用一个脚本,来实现监控并抱紧。

二,通过脚本来监控FULL GC .

开启日志功能。

在JAVA的启动参数里面,增加 -Xloggc:/var/log/gc.log

例如:

a407f9fc9407f34583a5865b93999ba3.png

我们先来看一段CMS gc所导出的日志

4b532f8ae31e96d94f8022be5bee5e54.png

日志里面记录了YGC及FULL GC的所有状态。

我们需要取出哪些数据呢。

20167.480: [CMS-concurrent-reset-start]

20167.488: [CMS-concurrent-reset: 0.009/0.009 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

20222.330: [GC 20222.330: [ParNew: 1029046K->15111K(1105920K), 0.0483250 secs] 1555881K->546542K(2437120K), 0.0485950 secs] [Times: user=0.29 sys=0.01, real=0.04 secs]

上面的数据是我复制的一份log日志。其中,我们要取出 15111K 及 546542K(红色标记),即执行full gc后第一次YGC的值。 15111K 是新生代在gc后还占用的内存大小,546542K 是整个堆的大小,我们知道,堆就是JAVA运行所占用的内存总大小,包括新生代占用大小,和 老年代内存占用大小。如果要计算出老年代所占用的大小,就把 总的 减掉 新生代大小就可以。最后和总的进行比对。即下面的脚本:#vim check_gc.sh

#! /bin/bash

#script by yaozhibing

#blog:http://www.yzbing.info/ ;http://yaozb.blog.51cto.com/

#QQ:410018348

datetime=`date -d today +"%Y-%m-%d %T"`

pro="MIC_EN"

network="TEL"

localip=`ifconfig eth0|awk -F"[: ]+" '/inet /{print $4}'`

gc_logpath="/var/log/gc.log"

error="80"

sms_file="/tmp/sms_file"

time_file="/tmp/time_file"

last=`cat $time_file||echo "111">$time_file`

now=`awk -F: '/CMS-concurrent-reset-start/{print $1}' $gc_logpath|tail -1`

if [ $now != $last ];then

echo $now >$time_file

total=`grep -oP '\d+(?=K\)\])' $gc_logpath|tail -1`

use=`grep -A1 "CMS-concurrent-reset:" $gc_logpath|tail -1|awk -F'[\\\>K]' '{print $7-$3}'`

ratio=`awk -v total=$total -v use=$use BEGIN'{print use/total*100}'`

if [ $(echo "$ratio <= $error"|bc) -eq 0 ];then

total_M=$(($total/1024))

free=$((($total-$use)/1024))

wget -O $sms_file http://短信接口/sms_send.php\?SMS_number=159XXXXX752\&SMS_content="$network:FULLGC ERROR on linux server $localip $pro (Total=$total_M M,Free=$free M,Use= $ratio%) $datetime"

fi

fi

并将些脚本添加到任务计划里面,每5分钟执行一次

#crontab -l

*/5 * * * * /bin/bash /job/check_gc.sh >/dev/null 2>&1

我们来对脚本进行简单的解释

#vim check_gc.sh

#! /bin/bash

#script by yaozhibing

#blog:http://www.yzbing.info/; http://yaozb.blog.51cto.com/

#QQ:410018348

datetime=`date -d today +"%Y-%m-%d %T"` #获取当前时间

pro="yzbing.info" #项目名称

network="TEL"

localip=`ifconfig eth0|awk -F"[: ]+" '/inet /{print $4}'` #主机ip

gc_logpath="/var/log/gc.log" #日志地址

error="80" #报警阀值

sms_file="/tmp/sms_file" #短信临时文件

time_file="/tmp/time_file" #比对文件

last=`cat $time_file||echo "111">$time_file` #读取这个文件内容,如果空的,先随便输一个值进去

now=`awk -F: '/CMS-concurrent-reset-start/{print $1}' $gc_logpath|tail -1` #取日志最前面的值 列

20167.488 ,这步主要是下一次和上一次进行比对,如果值是一样的,就不执行了,以免发生重复报警。

if [ $now != $last ];then #判断两次值是否不相等,

echo $now >$time_file #如果不相等的话,将这次的值输入临时文件

total=`grep -oP '\d+(?=K\)\])' $gc_logpath|tail -1` #取年老代所设置的内存大小

use=`grep -A1 "CMS-concurrent-reset:" $gc_logpath|tail -1|awk -F'[\\\>K]' '{print $7-$3}'` #取总内存占用大小,减新生代占用内存大小,即老年代的内存大小

22

ratio=`awk -v total=$total -v use=$use BEGIN'{print use/total*100}'` #将老年代的占用内存大小与,总年老代设置的总内存大小进行比对 并乘以100 取百分比。

if [ $(echo "$ratio <= $error"|bc) -eq 0 ];then #拿百分比与告警阀值进行比对,看是否达到告警界限。

total_M=$(($total/1024)) #年老代设置的内存大小除以1024,以M为单位

free=$((($total-$use)/1024))#同上。

wget -O $sms_file http://短信接口/sms_send.php\?SMS_number=159XXXXX752\&SMS_content="$network:FULLGC ERROR on linux server $localip $pro (Total=$total_M M,Free=$free M,Use= $ratio%) $datetime" #发送短信。当然也可以发送邮件报警。

fi

fi

目前脚本运行稳定,如有问题,请联系:410018348

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值