You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							118 lines
						
					
					
						
							4.5 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							118 lines
						
					
					
						
							4.5 KiB
						
					
					
				| <?php | |
| /** | |
|  * 启动并监控cron的队列脚本状态 | |
|  * | |
|  * @copyright (c) 2010, weibo All rights reserved. | |
|  * @author 王勇 <wangyong1@staff.sina.com.cn> | |
|  * @version 2.0 - 2011-11-25 | |
|  * @package Daemon | |
|  */ | |
| 
 | |
| include_once(dirname(dirname(dirname(__FILE__)))."/library/publicBase.php"); | |
| 
 | |
| date_default_timezone_set("Asia/Shanghai"); | |
| abstract class cronBase { | |
|     protected $process;                     // 队列进程列表,必选项 | |
|     protected $procnumlist;                 // 队列进程数限制,必选项 | |
|     protected $procnum = 0;                 // 默认启动进程数 | |
|     protected $maxtimelist;                 // 队列进程最大执行时间限制列表 | |
|     protected $maxtime = 480;               // 队列一次循环的默认最长时间, 未自定义则该项有效, 超过该值进程将被杀死 | |
|     protected $bin_php = '/usr/local/bin/php'; // php执行文件路径 | |
|  | |
|     private $path_daemon;               // ROOT根目录 | |
|     private $proc_start;                // 启动队列的进程信息 | |
|     private $path_prochealth;           // 进程健康路径 | |
|     private $path_conf;                 // 配置文件路径 | |
|  | |
|     public function __construct() { | |
|         $this->path_conf = dirname(dirname(__FILE__))."/config/daemonconf.php"; | |
|         include_once($this->path_conf); | |
| 
 | |
|         $this->path_daemon = dirname(dirname(dirname(__FILE__))).'/queue/deal/'; | |
|         $this->path_prochealth = dirname(dirname(dirname(__FILE__))).'/queue/cache/proc/deal_%s.txt'; | |
| 
 | |
|         $this->setPara(); | |
|         $this->prepare(); | |
|         $this->checkProc(); | |
|         $this->startProc(); | |
| 
 | |
|         return true; | |
|     } | |
| 
 | |
|     /* 子类必须实现,设置队列运行所须属性 */ | |
|     public abstract function setPara(); | |
| 
 | |
|     private function prepare() { | |
|         $dir_prochealth = dirname($this->path_prochealth); | |
|         if(!is_dir($dir_prochealth)) system("mkdir -p $dir_prochealth"); | |
|         if(empty($this->process)) exit("No dealscript.\n"); | |
|     } | |
| 
 | |
|     private function checkProc() { | |
|         $obj = new mBase(); | |
|         $server_ip = $obj->getServerIp(); | |
| 
 | |
|         $rdobj = $obj->initRedis(); | |
|         // 检测 | |
|         foreach($this->process as $deal_flag => $proc) { | |
|             $active_proc_codes = array(); | |
|             // 搜集存活的进程号、数 | |
|             $path_proc = $this->path_daemon.$proc; | |
| 
 | |
|             $chk_shell = "ps -ef|grep '{$path_proc}'|grep -v grep|grep -v '\/bin\/sh'|awk -F ' ' '{print $2\" \"$10\" \"$11}'"; | |
| 
 | |
|             $maxtime = $this->maxtimelist[$deal_flag]+0>0 ? $this->maxtimelist[$deal_flag] : $this->maxtime; | |
| 
 | |
|             $fp = @popen($chk_shell, 'r'); | |
| 
 | |
|             while (!feof($fp)) { | |
|                 $buffer = fgets($fp, 4096); | |
|                 $procinfo = explode(' ', trim($buffer)); | |
| 
 | |
|                 $procid = $procinfo[0]+0; | |
|                 $proc_code = is_numeric($procinfo[2]) ?  $procinfo[2] : $procinfo[1]+0; | |
| 
 | |
|                 if($procid==0) continue; | |
| 
 | |
|                 // 杀死僵死进程 | |
|                 $lasttime = $rdobj->get(sprintf(_DAEMON_HEALTH, $server_ip, $deal_flag, $proc_code)); | |
| 
 | |
|                 if($lasttime === false || time()-$lasttime > $maxtime) { | |
|                     system("/bin/kill -9 $procid"); | |
|                     error_log('['.date('Y-m-d H:i:s').']kill:'.$path_proc.'|'.$proc_code.'_'.md5($path_proc).'|'.time().'|'.$lasttime.'|'.$maxtime."\n", 3, dirname(dirname(__FILE__)).'/cache/proc/cron_track.log'); | |
| 
 | |
|                 } else { | |
|                     // 存活的进程 | |
|                     $active_proc_codes[] = $proc_code; | |
|                 } | |
|             } | |
| 
 | |
|             $procnum = $this->procnumlist[$deal_flag]+0>0 ? $this->procnumlist[$deal_flag] : $this->procnum; | |
|             for($i=0;$i<$procnum;$i++) { | |
|                 if(in_array($i, $active_proc_codes)) continue; | |
|                 $this->proc_start[$deal_flag]['proc'] = $path_proc; | |
|                 $this->proc_start[$deal_flag]['startnum'][] = $i; | |
|             } | |
|             if($fp) @pclose($fp); | |
|         } | |
|     } | |
| 
 | |
|     /* 检查进程运行情况检测, 杀僵死进程, 启动进程 */ | |
|     private function startProc() { | |
|         // 启动队列 | |
|         if(empty($this->proc_start)) return ; | |
|         foreach($this->proc_start as $deal_flag => $proc) { | |
|             if(empty($proc['startnum'])) continue; | |
| 
 | |
|             foreach ($proc['startnum'] as $proc_code) { | |
|                 $cmd = "{$this->bin_php} {$proc['proc']} {$deal_flag} {$proc_code} &"; | |
|                 //echo $cmd."\n"; | |
|                 //error_log('['.date('Y-m-d H:i:s').']startproc:'.$cmd."\n", 3, dirname(__FILE__).'/cron_track.log'); | |
|                 $fp = @popen($cmd, "r"); | |
|                 if($fp) @pclose($fp); | |
|             } | |
|         } | |
|     } | |
| 
 | |
| } | |
| 
 | |
| 
 |