centos中shell定时检测mysqld,nginx,httpd服务脚本

  • 2016-2-22 10:10
  • PHP二次开发
  • 阅读(3147)
  • 评论(0)
  • 来源:互联网
  • 摘要: 现在我们会发现很多个人站长的博客都会有不定时的打不开,要不是mysql数据库停止了,要么是nginx 502了或者apache不运行了,为了防止网站出现此问题我们给各位整理了一些监控这些服务是不是正常工作的代码,希望可帮 ...
    现在我们会发现很多个人站长的博客都会有不定时的打不开,要不是mysql数据库停止了,要么是nginx 502了或者apache不运行了,为了防止网站出现此问题我们给各位整理了一些监控这些服务是不是正常工作的代码,希望可帮助大家。
    前几天发现网站打不开,提示数据库连接错误,我登录linux 发现mysqld服务不知道什么时候停止了。幸好我即使发现。
    于是决定写一个shell脚本每分钟自动检测mysqld服务,如果发现服务没起来就自动启动mysqld服务
    也就是:通过cron定时任务执行检测脚本

    编写检测脚本 /root/bin/check

    #!/bin/bash
     
    check=`pgrep mysql`
     
    if [ -n "$check" ]; then
            exit
    else
            date=$(date +"%Y-%m-%d %H:%M:%S")
            /etc/init.d/mysqld  start
            echo 'error: mysqld at ' $date
    fi

    说明:也可以修改check=`pgrep mysql` 比如 check=`pgrep httpd` 或者 check=`pgrep nginx`来监测其他服务

    编辑cron执行

    crontab -e

    cron内容如下,其中注释掉了一行,可选择性编写

    #* * * * * sh /root/bin/check > /dev/null 2>&1 #执行后不发送结果邮件
    * * * * * sh /root/bin/check >> /root/bin/log.txt #执行后发送结果到指定文件

    由于cron每次执行后如果有输出则会默认发送邮件到 /var/spool/mail/root 长时间会导致 此文件有很多无用记录

    我们可以用 > /dev/null 2>&1 忽略结果写入

    当然也可以用 >> /root/bin/log.txt 写入到指定文件(要事先建立好文件)

    符:

    cron命令行简要说明
    分 时 日 月 星期 命令行
    例: */5 * * * * cmd #表示每5分钟执行一次命令

    command > filename 把标准输出重定向到一个新文件中
    command >> filename 把标准输出重定向到一个文件中(追加)
    command 1 > fielname 把标准输出重定向到一个文件中
    command > filename 2>&1 把标准输出和标准错误一起重定向到一个文件中
    command 2 > filename 把标准错误重定向到一个文件中
    command 2 >> filename 把标准输出重定向到一个文件中(追加)
    command >> filename 2>&1 把标准输出和标准错误一起重定向到一个文件中(追加)
    command < filename >filename2 把command命令以filename文件作为标准输入,以filename2文件作为标准输出
    command < filename 把command命令以filename文件作为标准输入
    command << delimiter 把从标准输入中读入,直至遇到delimiter分界符
    command <&m 把文件描述符m作为标准输入
    command >&m 把标准输出重定向到文件描述符m中
    command <&- 把关闭标准输入
    command 2>&1 把command命令标准错误重定向到标准输出

    下面的shell通过一个while-do循环,用ps -ef|grep 检查loader进程是否正在运行,如果没有运行,则启动,这样就保证了崩溃挂掉的进程重新被及时启动。
    必须注意两点:

    1、ps |grep 一个进程时必须加上其路劲,否则容易grep到错误的结果;
    2、必须用 -v 从结果中去除grep命令自身,否则结果非空。
     
    #!/bin/sh
    #=====================
    #php2.cc
    #=====================
    while :
    do
      echo "Current DIR is " $PWD
      stillRunning=$(ps -ef |grep "$PWD/loader" |grep -v "grep")
      if [ "$stillRunning" ] ; then
        echo "TWS service was already started by another way"
        echo "Kill it and then startup by this shell, other wise this shell will loop out this message annoyingly"
        kill -9 $pidof $PWD/loader
      else
        echo "TWS service was not started"
        echo "Starting service ..."
        $PWD/loader
        echo "TWS service was exited!"
      fi
      sleep 10
    done

     如果启动此shell时发现进程已经存在,说明以别的方式启动了进程而不是此shell,那么它会持续提醒找到进程,解决办法是,要么只用此shell启动服务,要么一经发现以其他方式启动的服务即kill掉,上面的语句就是这么干的:
     
        kill -9 $pidof $PWD/loader

    再补充一个监控nginx的shell脚本


    Nginx 虽然处理并发量比 apache 确实要强点,但它这种 php-cgi 模式不是太稳定,这点网上也有朋友总结了,我在实现项目中也感受到了。

    我们一台支付机,偶尔会出现以下情况的:php-cgi 进程突然消失了,造成PHP脚本无法访问;更不可思议的是明明是php-cgi 打开有两个端口在监听的,莫名其秒的突然有一个php-cgi 的端口被关闭了,造成所有请求全积在一个端口上,
    结果造成PHP脚本访问异常。

    基本这种情况,我写了个监控shell脚本的解决方案,不管以上出现那种情况,都自动恢复Nginx的服务.该脚本在生产环境上运行正常:

    #!/bin/bash
    #
    # filename: webservermonitor.sh
    # 功能:监控 nginx 的 php-cgi 是否正常
    # 作者:php2.cc
    # 运行: webservermonitor.sh &
    #
    
    # php-cgi 监听的IP和端口
    V_PHP_CGI_PORT="127.0.0.1:9000 127.0.0.1:9001"
    
    # nginx重启的脚本
    V_NGINX="/usr/local/nginx/sbin/restart.sh"
    
    # 日志文件
    V_LOG="/tmp/webservermonitor.log"
    
    # 函数定义:重启nginx
    function restart_nginx(){
        echo "----- `date` -----" >> $V_LOG
        echo "------------------" >> $V_LOG
        echo "`ps aux |grep 'nginx'`" >> $V_LOG
        echo "------------------" >> $V_LOG
        echo "`ps aux |grep 'php-cgi'`" >> $V_LOG
        echo "------------------" >> $V_LOG
        echo "`netstat -nlpt | grep 'php-cgi'`" >> $V_LOG
        echo "------------------" >> $V_LOG
        $V_NGINX  >> $V_LOG
    }
    
    # 循环执行,不采用 crontab ,国为 crontab 最小单位是分钟,时间太长了
    while :
    do
    
        # 1:先检测 nginx 主进程是否存在
        V_NGINX_NUM=`ps axu |grep 'nginx' |grep -v 'grep' |wc -l`
        if [ $V_NGINX_NUM -lt 1 ];then
            restart_nginx
            continue
        fi
    
        # 2:再检查php-cgi是否有进程存在
        V_PHP_CGI_NUM=`ps axu |grep 'php-cgi' |grep -v 'grep' |wc -l`
        if [ $V_PHP_CGI_NUM -lt 1 ];then
            restart_nginx
            continue
        fi
    
        # 3:再判断端口是否正常
        for PORT in $V_PHP_CGI_PORT
        do
            V_NUM=`eval "netstat -nlpt | grep '${PORT}' | wc -l"`
            if [ $V_NUM -lt 1 ];then
                restart_nginx
                continue
            fi
        done
    
        # 休眠
        sleep 5
    done

    ps:当然现在有一些服务器也提供方法像dnspod就提供了域名监控功能,可以监控到服务器是否正常哦。


    PHP技术交流QQ群:422137578

    除非注明,文章均为 PHP二次开发 原创,转载请注明本文地址:http://www.php2.cc/article-2134-1.html

    相关阅读

    最新评论

    用户名:  *

    邮 箱:  *

    网 址: 注意加上“http://”哦!