单机监控-shell脚本监测java应用程序是否宕机

前言

 由于工作中很多项目需要java应用程序在后台执行任务,但是有些时候后台运行的java应用程序会莫名其妙的死掉,此时运维/运营人员无法及时发现宕机的应用程序,只能够通过业务流程不正常才能够发现宕机的应用,对业务有很大的影响,由于公司服务器资源比较有限,无法部署统一的监测系统,特采用shell脚本的方式来监测java的应用进程是否正常运行,无须在业务代码中嵌入监控代码,做到低耦合,高内聚。

监测原理
  • 原理图
    在这里插入图片描述
    • java应用启动时,采用自定义脚本方式启动,然后将应用的当前进程号进行应用的根目录下生成pid.txt文件
    • shell脚本执行的时候查找指定目录下的所有pid.txt文件,然后根据每个pid.txt中的进程号判断当前的进程是否存活
    • 如果根据进程号没有找到指定的进程则认为进程死掉,主动发送告警(此处采用钉钉群机器人的方式告警)
监控脚本
  • java应用启动脚本

    #!/bin/sh
    
    root_dir=$(dirname $(readlink -f "$0")) 
    class_path=$root_dir/bin:$root_dir/lib/*
    pid_file=$root_dir/pid.txt
    console_file=$root_dir/logs/console.out
    error_file=$root_dir/logs/errors.out
    
    echo "Starting channel app in $root_dir ..."
    if [ ! -f $pid_file ]; then
    
        nohup java -cp $class_path com.xxx.StartUp >> $console_file 2>&1 &
        echo $! > $pid_file
    
        echo "[$(date)]: app in $root_dir started successful!" >> $console_file
        echo "pid = $!" >> $console_file
    
        echo "[$(date)]: app in $root_dir started successful!"
        echo "pid = $!"
    
    else
    	echo "****** Starting FAILED!! channel app in $root_dir is already running !!!"
    fi
    
  • java应用停止脚本

    #!/bin/sh
    root_dir=$(dirname $(readlink -f "$0"))
    pid_file=$root_dir/pid.txt
    echo $root_dir
    
    if [ -f $pid_file ]; then
        PID=$(cat $pid_file);
        echo "Stopping app in $root_dir ..."
        kill $PID;
        echo "app [pid=$PID] in $root_dir has been stopped"
        rm $pid_file
    else
        echo "Stopping FAILED! app in $root_dir is not running !!!"
    fi
    
  • shell监控脚本

    #!/bin/sh
    ########################################
    #功能:自动检测java应用程序宕机,并主动钉钉告警
    #版本:1.1
    #作者:silly at 20190708
    #版本说明:
    #  v1.0
    #   1)实现通过进程来判断应用程序是否宕机
    #   2)检测到宕机后通过钉钉机器人发送消息到钉钉群里告警
    #	
    #  v1.1
    #	1)删除7天前的日志文件
    #	2)修复通过进程号判断是否宕机出现包含的bug
    #		例如:进程号330,此时有运行的34330,则grep 330 会出现两条记录,此时检测会认为宕机
    #			grep  $pid ===>grep -w $pid
    #	3)修复定时任务无法获取当前脚本所在目录,logPath="`pwd`/logs"  ===》logPath="/server/scripts/logs"  
    #	4)修复定时任务中ifconfig命令无法使用,ifconfig ===》/sbin/ifconfig
    #########################################
    
    #参数定义
    #监控目录
    monitorPath="/"
    #监控进程号文件名
    monitorProcess="pid.txt"
    #钉钉access_token
    ddAccessToken="xxx"
    ddUrl="https://oapi.dingtalk.com/robot/send?access_token=$ddAccessToken"
    #日志目录
    logPath="/server/scripts/logs"
    #日志文件
    logFile="${logPath}/auto_monitor_down_application_`date +%F`.log"
    #判断日志目录是否存在
    [ -d $logPath ] || mkdir -p $logPath
    #判断日志文件是否存在
    [ -f $logFile ] || touch $logFile
    
    #打印日志
    function logInfo(){
    	echo " `date '+%Y-%m-%d %H:%M:%S'` $1" >> $logFile
    }
    #发送钉钉消息
    function sendDingding(){
    	#获取当前的ip
    	localIp=`/sbin/ifconfig |grep inet |grep -v 127.0.0.1|grep -v inet6|awk '{print $2}'|tr -d "addr:"|tr "\n" "\t"`
    	applicationPath=`dirname $1`
    	#拼接钉钉消息
    	msgTopic="[单机检测宕机-发现宕机应用 ]"
    	msgIp="IP:$localIp"	
    	msgApplication="应用位置:$applicationPath"
    	msgTime="报警时间: `date '+%Y-%m-%d %H:%M:%S'`"
    	msgRemark="请运营人员立即联系技术排查问题"
    
    	msgContent=$msgTopic\\n\\n$msgIp\\n$msgApplication\\n$msgTime\\n\\n$msgRemark
    	ddMsgTemplate='{"msgtype": "text","text": {"content": "<DING_TALK_MSG_CONTENT>"}, "at": {"atMobiles": [], "isAtAll": true}}'
    
    	msg=${ddMsgTemplate/<DING_TALK_MSG_CONTENT>/$msgContent}
    	response=`curl $ddUrl -H 'Content-Type: application/json' -d "$msg"`
    	logInfo  $response
    }
    
    logInfo "monitor start"
    find $monitorPath -type f -name $monitorProcess  |while read file
    do
    	pid=`cat $file`
    	processCount=`ps -ef |grep -w $pid|grep -v 'grep'|wc -l`
    	if [ $processCount -eq 1  ]
    	then
    		logInfo " `dirname $file` runing"		  
    	else
    		logInfo " `dirname $file` shutdown"
    		sendDingding $file
    	fi
    done
    #删除7天前的日志文件
    find ${logPath}/ -type f -mtime +7 -name "*.log" |xargs rm -f
    
    logInfo "monitor end"
    

    发送钉钉消息可参考博文:https://blog.csdn.net/cen50958/article/details/92230109

  • 加入定时任务每10分钟执行一次

    #每隔10分钟检查java应用程序是否宕机
    */10 * * * * /bin/sh /server/scripts/auto_monitor_down_application.sh >/dev/null 2>&1 
    
运行效果

在这里插入图片描述