1 * * * * php /项目路径/yii main >/dev/null 2>&1 & */ class MainController extends Controller { const DURATION = 30; //主进程检查间隔时间 /** * [init] */ public function actionIndex() { //如果Main进程已经在运行了,则不启动,保持主进程只有一个 if ($this->checkMainProcess()) { echo "Main process is running. Please check it."; exit; } //每N秒检查一次任务列表 while (1) { $this->checkTasks(); sleep(self::DURATION); }; } /** * 扫描所有任务 */ public function checkTasks() { echo "\n Checking tasks......"; $list = WorkerScript::getRunScriptList(); foreach ($list as $task) { if (!is_string($task['controller']) || !is_string($task['action'])) { echo "\n this task has error!"; continue; } $program = $task['controller'] . '/' . $task['action']; $this->execTask($program); } } /** * 执行任务 * @param $program * @return bool */ public function execTask($program) { //现在只支持单进程,如果以后支持多个进程同时运行,需要修改这里的逻辑 if ($this->checkProcess($program)) { return false; } $dir = dirname(\Yii::$app->getBasePath()); //将任务放到后台执行 $cmd = "nohup php ".$dir."/yii " . $program." >/dev/null 2>&1 &"; echo "\n ".$cmd; exec($cmd); } /** * 杀掉任务 * @param $program */ public function killTask($program) { //避免误杀到其它(短字符的)进程 if (strlen($program) < 4) return false; $cmd = "ps -ef | grep " . $program . " | awk '{print $2}' | xargs kill -9"; exec($cmd); return !$this->checkProcess($program); } /** * 检查是否进程中已经有别的主进程 * @param $process * @return bool */ public function checkMainProcess() { $cmd = "ps -ef |grep -v grep|grep -v 'sh -c' | grep main"; exec($cmd, $output); return count($output) > 1; } public function checkProcess($process) { $cmd = "ps -ef |grep -v grep|grep -v 'sh -c' | grep " . $process; exec($cmd, $output); return count($output) > 0; } }