• swoole创建工作进程,执行滞后工作


    一,创建守候进程,因为这里不需要Server,也没有Client,数据交换通过redis进行

    <?php
    namespace KubaSaas;
    require_once __DIR__ . '/Core/ErrorHandle.php';
    use SwooleTimer;
    use SwooleProcess;
    use KubaSaasCoreErrorHandle;
    
    final class Services {
    
        private $m_workers = [];
        private $m_pid = 0;
    	
        public function __construct() {
            try {
                $this->m_pid = posix_getpid();
                
                echo "moolan_services start:".$this->m_pid.PHP_EOL;
                echo date("Y-m-d H:i:s").PHP_EOL;
                
                swoole_set_process_name("moolan_services");
    
                $this->create_error_monitor_process($this->m_pid);
    
                //监控子进程的状态,如果子进程异常退出,则重启该子进程
                $this->process_monitor();
            }catch (Exception $e){
                die('ALL ERROR: '.$e->getMessage());
            }        
        }
        
        private function process_monitor()
        {       
            //检测子进程是否结束,如果结束,则重新启动子进程 
            while(1) {
                if(count($this->m_workers)){
                    //这里会一直等待,一次接收一个子进程,所以外面必须有循环
                    $ret = swoole_process::wait();
                    if ($ret) {
                        $this->process_reboot($ret);
                    }
                }             
            }        
        }
        
        private function process_reboot($ret){
            try
            {
                $pid=$ret['pid'];
    
                if(in_array($pid, $this->m_workers)){
                    $method_name = $this->m_workers[$pid];
                    unset($this->m_workers[$pid]);
    
                    echo $method_name." restart:".$pid.PHP_EOL;
                    echo date("Y-m-d H:i:s").PHP_EOL;                
                    
                    $method = new ReflectionMethod($this, $method_name);
                    $method->invoke($this, [$this->m_pid]);
    
                    return;
                }
            }
            catch (Exception $e)
            {
                die('Process_reboot error: '.$e->getMessage());
            }
        }    
        
        /**
         * 创建监控系统错误的进程
         * 
         * 该进程属于一条一条处理的模式,因为错误不会太多
         */
        private function create_error_monitor_process($mpid)
        {
            try
            {
                $process = new Process(function ($worker) use ($mpid)
                {
                    try
                    {               
                        swoole_set_process_name("moolan_error_handle");
    
                        $obj_error_handle = new ErrorHandle();
                        while (true)
                        {
                            try
                            {
                                //从消息队列接收出错消息,接收到一个,就启动一个task去执行                
                                //如果接收不到出错信息,则休息2秒时间
                                if (!$obj_error_handle->fetch_task())
                                {
                                    $obj_error_handle->release_task();
                                    unset($obj_error_handle);
    
                                    usleep(2000000);
    
                                    $obj_error_handle = new ErrorHandle();
                                }
                                else
                                {
                                    //启动任务处理接收到的出错信息
                                    $obj_error_handle->do_task();
                                }
    
                                //执行完一个完成的任务后,
                                //查看主进程是否已经关闭,如果已经关闭,则子进程也要关闭运行
                                if(!swoole_process::kill($mpid,0)){
                                    echo 'moolan service gone'.PHP_EOL;
                                    echo __METHOD__.' process exit'.PHP_EOL;
                                    $worker->exit();
                                }
                            }
                            catch (Exception $e)
                            {
                                echo $e->getMessage();
                            }
                        }   
                    }
                    catch (Exception $e)
                    {
                        die(__METHOD__.' process exec error: '.$e->getMessage());
                    }
                }, false);
    
                $pid = $process->start();
                
                echo __METHOD__." started:".$pid.PHP_EOL;
                echo date("Y-m-d H:i:s").PHP_EOL;             
                
                $this->m_workers[$pid] = __METHOD__;
            }
            catch (Exception $e)
            {
                die(__METHOD__.' Process Start error: '.$e->getMessage());
            }
        }
    
    }
    
    $server = new Services();
    

      二,创建值守脚本,检测以上主进程持续运行

    #! /bin/sh
    
    proc_name="***"                    # 进程名
    proc_file="***.php"
    log_name="/***/moolan-monitor.log"                  # 日志文件
    pid=0
    
    proc_num()                                             # 计算进程数
    {
            num=`ps -ef | grep $proc_name | grep -v grep | wc -l`
            return $num
    }
    
    proc_id()                                               # 进程号
    {
            pid=`ps -ef | grep $proc_name | grep -v grep | awk '{print $2}'`
    }
    
    proc_num
    number=$?
    if [ $number -eq 0 ]                                    # 判断进程是否存在
    then 
            nohup /usr/local/php5/bin/php /***/$proc_file >>$log_name 2>&1 &                 # 重启进程的命令,请相应修改
            proc_id                                               # 获取新进程号
            echo ${pid}, `date` >>  $log_name                    # 将新进程号和重启时间记录
    fi
    

      三,把值守脚本加入到定时器

    crontab

    利用定时任务来轮询执行脚本

    */1 * * * * /PATH/watch_queue.sh

  • 相关阅读:
    mysql(一)
    spring
    数据库连接池
    spring jdbctemplate
    HDU-4219-Randomization?
    离线赛总结
    HDU-4507-吉哥系列故事-恨7不成妻
    HDU-1204-糖果大战
    [BZOJ1150][CTSC2007]数据备份
    二分图学习笔记
  • 原文地址:https://www.cnblogs.com/si812cn/p/7772888.html
Copyright © 2020-2023  润新知