网站首页学无止境LINUX

服务器自动监控Shell脚本

发布时间:2014-10-24 22:48:14编辑:songlin阅读(53)

    一、使用方法:
    1. git clone git://gist.github.com/1216837.git gist-1216837 
    2. vim gist-1216837/sys-mon.sh //修改内存、CPU等预设阀值 
    3. mkdir /var/script 
    4. mv gist-1216837/sys-mon.sh /var/script 

    设置每分钟执行一次

    1. crontab -e 
    2. * * * * * /bin/bash  /var/shell/sys-mon.sh 

    二、Shell脚本内容

    1. #! /bin/bash 
    2. #==================================================================== 
    3. # sys-mon.sh 
    4. # 
    5. # Copyright (c) 2011, WangYan  
    6. # All rights reserved. 
    7. # Distributed under the GNU General Public License, version 3.0. 
    8. # 
    9. # Monitor system mem and load, if too high, restart some service. 
    10. # 
    11. # See: http://wangyan.org/blog/sys-mon-shell-script.html 
    12. # 
    13. # V 0.5, Date: 2011-12-08 
    14. #==================================================================== 
    15.  
    16. # Need to monitor the service name 
    17. # Must be in /etc/init.d folder exists 
    18. NAME_LIST="httpd nginx mysql" 
    19.  
    20. # Single process to allow the maximum CPU (%) 
    21. PID_CPU_MAX="25" 
    22.  
    23. # The maximum allowed memory (%) 
    24. PID_MEM_SUM_MAX="95" 
    25.  
    26. # The maximum allowed system load 
    27. SYS_LOAD_MAX="6" 
    28.  
    29. # Log path settings 
    30. LOG_PATH="/var/log/sys-mon.log" 
    31.  
    32. # Date time format setting 
    33. DATA_TIME=$(date +"%y-%m-%d %H:%M:%S"
    34.  
    35. # Your email address 
    36. EMAIL="webmaster@example.com" 
    37.  
    38. # Your website url 
    39. MY_URL="http://106.187.38.210/p.php" 
    40.  
    41. #==================================================================== 
    42.  
    43. for NAME in $NAME_LIST 
    44. do 
    45.     PID_CPU_SUM="0";PID_MEM_SUM="0" 
    46.     PID_LIST=`ps aux | grep $NAME | grep -v root` 
    47.  
    48.     IFS_TMP="$IFS";IFS=$'\n' 
    49.     for PID in $PID_LIST 
    50.     do 
    51.         PID_NUM=`echo $PID | awk '{print $2}'
    52.         PID_CPU=`echo $PID | awk '{print $3}'
    53.         PID_MEM=`echo $PID | awk '{print $4}'
    54. #       echo "$NAME: PID_NUM($PID_NUM) PID_CPU($PID_CPU) PID_MEM($PID_MEM)" 
    55.  
    56.         PID_CPU_SUM=`echo "$PID_CPU_SUM + $PID_CPU" | bc` 
    57.         PID_MEM_SUM=`echo "$PID_MEM_SUM + $PID_MEM" | bc` 
    58.  
    59.         if [ `echo "$PID_CPU >= $PID_CPU_MAX" | bc` -eq 1 ];then 
    60.             if [[ "$NAME" = "php-fpm" || "$NAME" = "httpd" ]];then 
    61.                 sleep 5 
    62.                 if [ `echo "$PID_CPU >= $PID_CPU_MAX" | bc` -eq 1 ];then 
    63.                     echo "${DATA_TIME}: kill ${NAME}($PID_NUM) successful (CPU:$PID_CPU)" | tee -a $LOG_PATH 
    64.                     kill $PID_NUM 
    65.                 fi 
    66.             else 
    67.                 echo "${DATA_TIME}: [WARNING!] ${NAME}($PID_NUM) cpu usage is too high! (CPU:$PID_CPU)" | tee -a $LOG_PATH 
    68.             fi 
    69.         fi 
    70.     done 
    71.     IFS="$IFS_TMP" 
    72.  
    73.     SYS_LOAD=`uptime | awk '{print $(NF-2)}' | sed 's/,//'
    74.     SYS_MON="CPU:$PID_CPU_SUM MEM:$PID_MEM_SUM LOAD:$SYS_LOAD" 
    75. #   echo -e "$NAME: $SYS_MON\n" 
    76.  
    77.     SYS_LOAD_TOO_HIGH=`awk 'BEGIN{print('$SYS_LOAD'>'$SYS_LOAD_MAX')}'
    78.     PID_MEM_SUM_TOO_HIGH=`awk 'BEGIN{print('$PID_MEM_SUM'>'$PID_MEM_SUM_MAX')}'
    79.  
    80.     if [[ "$SYS_LOAD_TOO_HIGH" = "1" || "$PID_MEM_SUM_TOO_HIGH" = "1" ]];then 
    81.         /etc/init.d/$NAME stop 
    82.         sleep 5 
    83.         for ((i=1;i<4;i++)) 
    84.         do 
    85.             if [ `pgrep $NAME | wc -l` = "0" ];then 
    86.                 echo "$DATA_TIME: Stop $NAME successful! ($SYS_MON)" | tee -a $LOG_PATH 
    87.                 break 
    88.             else 
    89.                 echo "${DATA_TIME}: [WARNING!] Stop $NAME failed[$i]! ($SYS_MON)" | tee -a $LOG_PATH 
    90.                 pkill $NAME && killall $NAME 
    91.             fi 
    92.         done 
    93.         /etc/init.d/$NAME start 
    94.         sleep 5 
    95.         for ((ii=1;ii<4;ii++)) 
    96.         do 
    97.             if [ `pgrep $NAME | wc -l` != "0" ];then 
    98.                 echo "$DATA_TIME: Start $NAME successful!" | tee -a $LOG_PATH 
    99.                 break 
    100.             else 
    101.                 echo "${DATA_TIME}: [WARNING!] Start $NAME failed[$ii]! ($SYS_MON)" | tee -a $LOG_PATH 
    102.                 /etc/init.d/$NAME start 
    103.                 sleep 5 
    104.             fi 
    105.         done 
    106.         if [ `pgrep $NAME | wc -l` != "0" ];then 
    107.             echo "${DATA_TIME}: [ERROR!] Start $NAME failed! ($SYS_MON)" | mail -s "Start $NAME failed" $EMAIL 
    108.         fi 
    109.     fi 
    110. done 
    111.  
    112. STATUS_CODE=`curl -o /dev/null -s -w %{http_code} $MY_URL` 
    113. #echo -e "STATUS CODE: $STATUS_CODE\n" 
    114.  
    115. if [ "$STATUS_CODE" != "200" ];then 
    116.     sleep 3 
    117.     STATUS_CODE=`curl -o /dev/null -s -w %{http_code} $MY_URL` 
    118.     if [ "$STATUS_CODE" != "200" ];then 
    119.         echo "${DATA_TIME}: [WARNING!] Website Downtime! ($SYS_MON)" | tee -a $LOG_PATH 
    120.         echo "${DATA_TIME}: [WARNING!] Website Downtime! ($SYS_MON)" | mail -s "Start $NAME failed" $EMAIL 
    121.     fi 
    122. fi 
    123.  

    脚本内容不难理解,原理解释可参考《Linux 进程自动监控shell脚本》

    三、注意事项

    1、NAME_LIST 指定的监控程序必须在/etc/init.d 文件夹中存在,并且支持stop和start操作

    2、PID_CPU_MAX 指的是单个进程的CPU占用,只针对php-fpm或httpd。

    3、PID_MEM_SUM_MAX 指的是该程序所有进程实际内存占用,而并非系统总内存。

    4、EMAIL 只有在程序启动失败后,你才能收到邮件提醒。

    四、调试(补充,以上为WangYan Blog 原文章


    脚本写完之后让我们运行一下,当然脚本里面的EMail 和 weburl还是需要改成你自己的,结果:

    1. ./xxx.sh # xxx为自命名 

     

    1. ./pid_auto_reboot.sh: line 57: bc: command not found 
    2. ./pid_auto_reboot.sh: line 59: bc: command not found 
    3. ./pid_auto_reboot.sh: line 59: [: -eq: unary operator expected 
    4. ./pid_auto_reboot.sh: line 56: bc: command not found 
    5. ./pid_auto_reboot.sh: line 57: bc: command not found 
    6. ./pid_auto_reboot.sh: line 59: bc: command not found 
    7. ./pid_auto_reboot.sh: line 59: [: -eq: unary operator expected 
    8. ./pid_auto_reboot.sh: line 56: bc: command not found 
    9. ./pid_auto_reboot.sh: line 57: bc: command not found 
    10. ./pid_auto_reboot.sh: line 59: bc: command not found 
    11. ./pid_auto_reboot.sh: line 59: [: -eq: unary operator expected 
    12. ./pid_auto_reboot.sh: line 56: bc: command not found 
    13. ./pid_auto_reboot.sh: line 57: bc: command not found 
    14. ./pid_auto_reboot.sh: line 59: bc: command not found 
    15. ./pid_auto_reboot.sh: line 59: [: -eq: unary operator expected 
    16. awk: BEGIN{print(>95)} 
    17. awk:             ^ syntax error 
    18. awk: BEGIN{print(>95)} 
    19. awk:                 ^ syntax error 
    20. ./pid_auto_reboot.sh: line 56: bc: command not found 
    21. ./pid_auto_reboot.sh: line 57: bc: command not found 
    22. ./pid_auto_reboot.sh: line 59: bc: command not found 
    23. ./pid_auto_reboot.sh: line 59: [: -eq: unary operator expected 

    什么问题? 哦原来是没有bc命令 没关系,没有我们就安装一下嘛,我用的是CentOs 直接

    1. yum -y install bc 

    安装一下。再运行搞定。

本文来源地址:http://wangyan.org/blog/sys-mon-shell-script.html