zoukankan      html  css  js  c++  java
  • 一个简单的脚本守护进程

    https://www.baidufe.com/item/9565cec0004cb49d25fd.html

    一、背景

    项目过程中,经常会有很多的脚本,Shell脚本PHP脚本Python脚本等,更有一些脚本是需要常驻内存执行的,简而言之就是需要while(true){}的模式执行。

    但是有的时候,一个常驻内存的进程会因为某些耗时操作而夯住,不再往下继续执行,成为了一个僵尸进程;或者因为某个操作偶然出错,直接退出了;所以我们需要有一套简单的机制来保证进程一直处于活跃状态。

    二、方案

    以一个PHP脚本为例:

    • 脚本中依然采用while(true){}方式,但是额外增加一个执行时间的控制,即,设定当前脚本执行超过某个时间之后,自动退出
    • 脚本自动退出之后,通过一个守护进程自动重启

    三、实现

    1、PHP脚本范例

    脚本名称:script/monitor/Collect.class.php

    class Collect extends FrameworkFrameworkScript {
    
        // 表示:脚本最多能活跃10分钟
        private $interval = 600;
    
        // 脚本入口
        public function run() {
    
            $start = time();
            while (true) {
                // here , do what you want to do...
    
                // 如果数据为空,则10分钟自杀进程
                if (time() - $start > $this->interval) {
                    exit(0);
                }
            }
        }
    }

    2、守护进程范例

    守护进程脚本名称:script/monitor/Watch.sh

    #!/bin/bash
    # @author xianliezhao
    
    # crontab命令:
    # 监控线上服务稳定性情况
    # */1 * * * * sh /home/work/script/monitor/Watch.sh start >> /home/work/logs/script_monitor_watch.log
    
    # PHP命令
    php="/home/service/php/bin/php /home/work/mlservice/goods/public/script.php"
    
    # 在这里配置所有需要【守护】的PHP进程
    proc_list='monitor\Collect monitor\RealtimeAnalytics'
    
    #work 账户运行
    name=$(whoami)
    if [ $name != 'work' ];then
        echo `date "+%Y/%m/%d %H:%M:%S> "` "必须用work账户"
        exit
    fi
    
    #开启服务
    start() {
        for proc in $proc_list ;do
            arrm=$(ps -ef | grep "`echo $proc`" | grep -v 'grep' | awk -F'script.php' '{print $2}'| wc -l)
            if [ ${arrm:-0} = 0 ];then
               $php $(echo $proc | awk -F"\" '{print $1"\"$3}') >/dev/null &
               echo  `date "+%Y/%m/%d %H:%M:%S> "` "$proc 进程已经重启"
            else
               echo `date "+%Y/%m/%d %H:%M:%S> "` "$proc 进程已经存在"
            fi
        done
    }
    
    #停止服务
    stop() {
        for proc in $proc_list ;do
            arrproc=$(ps -ef | grep "`echo $proc`" | awk '{print $2}')
            for p in $arrproc; do
                kill $p;
                echo `date "+%Y/%m/%d %H:%M:%S> "` $p " 进程已杀死!"
            done
        done
        echo `date "+%Y/%m/%d %H:%M:%S> "` "服务已停止!"
    }
    
    #check脚本是否运行
    check() {
        for proc in $proc_list ;do
            arrspar=$(ps -ef | grep "`echo $proc`" | grep -v 'grep' | awk '{print $2}')
            echo `date "+%Y/%m/%d %H:%M:%S> "` "目前运行的服务监控进程($proc):" ${arrspar:-"无"}
        done
    }
    
    usage() {
        cat <<EOF
            守护进程使用方法(需要 work 用户执行):
    
            usage: sh $0 check|start|stop|restart
            start       启动服务
            stop        停止服务
            check       检查服务是否正常
    EOF
            exit
    }
    
    while true;do
        case $1 in
            start)
                start
                break
                ;;   
            help)
                usage
                break
                ;;
            stop)
                stop
                break
                ;;
            check)
                check
                break
                ;;
            *)
                usage
                break
                ;;
        esac
        shift
    done

    四、使用

    1、使用帮助

    [work@script-01 monitor]$ sh Watch.sh
            守护进程使用方法(需要 work 用户执行):
    
            usage: sh Watch.sh check|start|stop|restart
            start       启动服务
            stop        停止服务
            check       检查服务是否正常

    2、检测脚本执行状态

    [work@script-01 monitor]$ sh Watch.sh check
    2015/09/24 15:10:48> 目前运行的服务监控进程(monitor\Collect): 65321
    2015/09/24 15:10:48> 目前运行的服务监控进程(monitor\RealtimeAnalytics): 无

    3、通过守护进程手动重启脚本

    [work@script-01 monitor]$ sh Watch.sh start
    2015/09/24 15:11:26> monitor\Collect 进程已经重启
    2015/09/24 15:11:26> monitor\RealtimeAnalytics 进程已经重启

    4、通过crontab自动守护

    # crontab命令:
    # 监控线上服务稳定性情况
    */1 * * * * sh /home/work/script/monitor/Watch.sh start >> /home/work/logs/script_monitor_watch.log

    每分钟检测一次,没有启动则自动重启!通过这种方式来保证,脚本一定不死。

  • 相关阅读:
    在C++中使用GDI+绘制带箭头的线,箭头大小可调
    tomcat通过conf-Catalina-localhost目录发布项目详解
    VC++ 获取Windows系统标准字体方法
    简单实现全屏对话框
    采用ATL实现无模板对话框的显示
    C++实现全局鼠标、键盘消息hook,支持事件
    C++ FastDelegate 扩展,实现与.net类似的事件处理功能
    技术研发在国内的现状
    [STM32F103]DMA原理
    [STM32F103]RTC日历
  • 原文地址:https://www.cnblogs.com/doseoer/p/5626930.html
Copyright © 2011-2022 走看看