<?php
/**
* Created by PhpStorm.
* User: nihao
* Date: 2018/9/15
* Time: 10:21
*/
namespace app\process;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class ProcessCommand extends Command
{
protected static $pid_file = "./runtime/console.pid";
public static function getMid(){
return file_get_contents(self::$pid_file);
}
protected function configure()
{
$this
->setName('all')
->setDescription('process name')
->setHelp('This command allows you to start a process...')
->addArgument(
'process',
InputArgument::REQUIRED,
'进程名是必须参数'
) ;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$name = $input->getArgument('process');
$worker = Process::getInstance();
switch ($name){
case "reload":
$pid = file_get_contents(self::$pid_file);
if(!file_exists(self::$pid_file)){
$output->writeln("进程pid文件不存在,未启动进程,不能reload");
exit;
}
// \swoole_process::kill($pid,SIGUSR1);
//确保删除子进程
$process = new \swoole_process(function ( $worker) {
$worker->exec('/bin/sh', array('-c', "ps aux|grep blink-console |grep -v grep|grep -v blink-console-master|awk '{print $2}' |xargs kill -SIGTERM"));
$worker->exit(0);
}, true); // 需要启用标准输入输出重定向
$process->start();
break;
case "start":
if(file_exists(self::$pid_file)){
$output->writeln("进程pid文件已存在");
exit;
}
\swoole_process::daemon(true,true);
swoole_set_process_name("blink-console-master");
file_put_contents(self::$pid_file, getmypid());
$worker->run();
$worker->processWait();
break;
case "stop":
if(file_exists(self::$pid_file)){
$pid = file_get_contents(self::$pid_file);
\swoole_process::kill($pid);
sleep(2);
@unlink(self::$pid_file);
}else{
//确保删除
$process = new \swoole_process(function ( $worker) {
$worker->exec('/bin/sh', array('-c', "ps aux|grep blink-console |grep -v grep|awk '{print $2}' |xargs kill -SIGTERM"));
$worker->exit(0);
}, true); // 需要启用标准输入输出重定向
$process->start();
}
exit;
case "status":
$process = new \swoole_process(function ( $worker) {
$ret = $worker->exec('/bin/sh', array('-c', "ps aux|grep blink-console "));
$worker->write(var_export($ret,true));
$worker->exit(0);
}, true); // 需要启用标准输入输出重定向
$process->start();
$output->writeln($process->read(). "\n");
break;
}
}
}
<?php
/**
* Created by PhpStorm.
* User: nihao
* Date: 2018/9/15
* Time: 10:21
*/
namespace app\process;
use app\http\controllers\TestController;
use blink\di\Container;
class Process
{
public $max_precess=1;
public $new_index=0;
public static $ins;
public static $pMap=[];
public static function getInstance(){
if(self::$ins){
return self::$ins;
}
return self::$ins = new static();
}
/**
* [
* 'task_name'=>[process_nums,task,task_name]
* ]
* @return array
*/
public function registerTaskList(){
return [
//不能通过[object,method] 方式创建任务,全部以static方法使用
'sync-fan'=>[1,['app\sync\Fan',"run"],"sync-fan"],
'sync-follow'=>[1,['app\sync\Follow',"run"],"sync-follow"],
'sync-friend'=>[1,['app\sync\Friends',"run"],"sync-friend"],
'sync-friendblack'=>[1,['app\sync\FriendsBlack',"run"],"sync-friendblack"],
'sync-MsgUnread'=>[1,['app\sync\MsgUnread',"run"],"sync-MsgUnread"],
'sync-MsgUnreadLog'=>[4,['app\sync\MsgUnreadLog',"run"],"sync-MsgUnreadLog"],
];
}
public function run(){
$taskList = $this->registerTaskList();
foreach ($taskList as $item){
for ($i= 0;$i<$item[0];$i++){
$this->CreateProcess($item[1],$item[2]);
}
}
}
public function CreateProcess($task,$task_name){
$process = new \swoole_process(function(\swoole_process $worker)use($task,$task_name){
swoole_set_process_name(sprintf('blink-console-worker-'.$task_name));
$this->checkMpid($worker);
call_user_func($task);
sleep(2);
}, false, false);
$pid=$process->start();
self::$pMap[$pid] = $task_name;
return $pid;
}
public function checkMpid(&$worker){
$mpid = (ProcessCommand::getMid());
if(!\swoole_process::kill((int)$mpid,0)){
// 这句提示,实际是看不到的.需要写到日志中
unset(self::$pMap[getmygid()]);
$worker->exit();
}
}
public function processWait(){
while(1) {
$result = \swoole_process::wait();
if($result){
$tasks = $this->registerTaskList();
$task_item = $tasks[self::$pMap[$result['pid']]];
if(!empty($task_item)){
$this->CreateProcess($task_item[1],$task_item[2]);
}
}
//$$result = array('code' => 0, 'pid' => 15001, 'signal' => 15);
}
}
}