예제 #1
0
 /**
  * 解析运行命令
  * php yourfile.php start | stop | restart | reload | status
  * @return void
  */
 protected static function parseCommand()
 {
     // 检查运行命令的参数
     global $argv;
     $start_file = $argv[0];
     if (!isset($argv[1])) {
         exit("Usage: php yourfile.php {start|stop|restart|reload|status|kill}\n");
     }
     // 命令
     $command = trim($argv[1]);
     // 子命令,目前只支持-d -f
     $command2 = isset($argv[2]) ? $argv[2] : '';
     // 记录日志
     $mode = '';
     if ($command === 'start') {
         if ($command2 === '-d') {
             $mode = 'in DAEMON mode';
         } else {
             $mode = 'in DEBUG mode';
             self::$force_delayed_kill = true;
         }
     }
     self::log("WorkerClient[{$start_file}] {$command} {$mode}");
     // 检查主进程是否在运行
     $master_pid = @file_get_contents(self::$pidFile);
     $master_is_alive = $master_pid && @posix_kill($master_pid, 0);
     if ($master_is_alive) {
         if ($command === 'start') {
             self::log("WorkerClient[{$start_file}] already running");
             exit;
         } else {
             if ($command2 === '-f') {
                 //向主进程发送SIGHUP信号,启用强制退出
                 self::$force_delayed_kill = true;
                 self::log("WorkerClient[{$start_file}] turn on force_delayed_kill");
                 $master_is_alive && posix_kill($master_pid, SIGHUP);
             }
         }
     } elseif ($command !== 'start' && $command !== 'restart') {
         self::log("WorkerClient[{$start_file}] not running");
     }
     // 根据命令做相应处理
     switch ($command) {
         case 'kill':
             exec("ps aux | grep {$start_file} | grep -v grep | awk '{print \$2}' |xargs kill -SIGINT");
             exec("ps aux | grep {$start_file} | grep -v grep | awk '{print \$2}' |xargs kill -SIGKILL");
             break;
             // 启动 workerclient
         // 启动 workerclient
         case 'start':
             if ($command2 === '-d') {
                 Worker::$daemonize = true;
             }
             break;
             // 显示 workerclient 运行状态
         // 显示 workerclient 运行状态
         case 'status':
             // 尝试删除统计文件,避免脏数据
             if (is_file(self::$_statisticsFile)) {
                 @unlink(self::$_statisticsFile);
             }
             // 向主进程发送 SIGUSR2 信号 ,然后主进程会向所有子进程发送 SIGUSR2 信号
             // 所有进程收到 SIGUSR2 信号后会向 $_statisticsFile 写入自己的状态
             posix_kill($master_pid, SIGUSR2);
             // 睡眠100毫秒,等待子进程将自己的状态写入$_statisticsFile指定的文件
             usleep(100000);
             // 展示状态
             readfile(self::$_statisticsFile);
             exit(0);
             // 重启 workerclient
         // 重启 workerclient
         case 'restart':
             // 停止 workeran
         // 停止 workeran
         case 'stop':
             self::log("WorkerClient[{$start_file}] is stopping ...");
             // 向主进程发送SIGINT信号,主进程会向所有子进程发送SIGINT信号
             $master_pid && posix_kill($master_pid, SIGINT);
             // 如果 $timeout 秒后主进程没有退出则展示失败界面
             $timeout = 5;
             $start_time = time();
             while (1) {
                 // 检查主进程是否存活
                 $master_is_alive = $master_pid && posix_kill($master_pid, 0);
                 if ($master_is_alive) {
                     // 检查是否超过$timeout时间
                     if (time() - $start_time >= $timeout) {
                         self::log("WorkerClient[{$start_file}] stop worker instantly fail");
                         if (self::$force_delayed_kill) {
                             self::log("WorkerClient[{$start_file}] SIGKILL will be sent to alive workers.");
                         }
                         exit;
                     }
                     usleep(10000);
                     continue;
                 }
                 self::log("WorkerClient[{$start_file}] stop success");
                 // 是restart命令
                 if ($command === 'stop') {
                     exit(0);
                 }
                 // -d 说明是以守护进程的方式启动
                 if ($command2 === '-d') {
                     Worker::$daemonize = true;
                 }
                 break;
             }
             break;
             // 平滑重启 workerclient
         // 平滑重启 workerclient
         case 'reload':
             posix_kill($master_pid, SIGUSR1);
             self::log("WorkerClient[{$start_file}] reload");
             exit;
             // 未知命令
         // 未知命令
         default:
             exit("Usage: php yourfile.php {start|stop|restart|reload|status|kill}\n");
     }
 }