swoole創建工作進程,執行滯後工作
阿新 • • 發佈:2017-11-02
php pid false brush class usr sta rest pac
一,創建守候進程,因為這裏不需要Server,也沒有Client,數據交換通過redis進行
<?php namespace Kuba\Saas; require_once __DIR__ . ‘/Core/ErrorHandle.php‘; use \Swoole\Timer; use \Swoole\Process; use Kuba\Saas\Core\ErrorHandle; 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
swoole創建工作進程,執行滯後工作