request->getParams(); $model = new DynamicModel([ 'option' => $params[1] ?? null ]); $model->addRule('option', 'default', ['value' => 'start']) ->addRule('option', 'required') ->addRule('option', 'string') ->addRule('option', 'in', ['range' => ['start', 'stop', 'restart']]) ->validate(); if ($model->hasErrors()) { throw new Exception($model->getFirstError('option'), 500); } $attributes = $model->getAttributes(); $this->option = $attributes['option']; return parent::beforeAction($action); } /** * 获取当前进程id * @Author bing * @DateTime 2021-10-15 11:01:31 * @copyright: Copyright (c) 2020 广东七件事集团 * @return void */ public function getPid() { return posix_getpid(); } /** * 创建pid保存文件 * @Author bing * @DateTime 2021-10-15 11:06:16 * @copyright: Copyright (c) 2020 广东七件事集团 * @return string */ public function getPidFile() { $uniqueId = $this->action->getUniqueId(); $pidPath = Yii::$app->getRuntimePath() . '/pid/'; FileHelper::createDirectory($pidPath); return $pidPath . StringHelper::replace('/', '_', $uniqueId) . '.pid'; } /** * 把pid写入文件内 * @Author bing * @DateTime 2021-10-15 11:11:52 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $pid * @return void */ public function writePid($pid = null) { if (empty($pid)) { $pid = $this->getPid(); } $pidFile = $this->getPidFile(); file_put_contents($pidFile, $pid . PHP_EOL, FILE_APPEND); } /** * 获取运行中的进程 * @Author bing * @DateTime 2021-10-15 11:13:33 * @copyright: Copyright (c) 2020 广东七件事集团 * @return array */ public function getPids() { $pidFile = $this->getPidFile(); @$pidString = file_get_contents($pidFile); $pids = array_filter(StringHelper::explode($pidString, PHP_EOL)); return $pids; } /** * 终止进程 * @Author bing * @DateTime 2021-10-15 11:16:49 * @copyright: Copyright (c) 2020 广东七件事集团 * @return void */ public function killPids(){ $pidFile = $this->getPidFile(); $pids = $this->getPids(); array_map(function ($value) { // 终止信号 posix_kill($value, SIGTERM); }, $pids); file_put_contents($pidFile, ''); } /** * 检查进程是否在运行中 * @Author bing * @DateTime 2021-10-15 11:20:14 * @copyright: Copyright (c) 2020 广东七件事集团 * @return void */ public function processRunningCheck(){ $pidFile = $this->getPidFile(); $pids = $this->getPids(); foreach ($pids as $pid) { if (file_exists('/proc/' . $pid)) { return true; } } file_put_contents($pidFile, ''); return false; } /** * 服务启动时处理进程管理 * @Author bing * @DateTime 2021-10-15 16:22:01 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $serv * @return void */ public function onStart($serv) { //管理master_id和manager_id $this->writePid($serv->master_pid); $this->writePid($serv->manager_pid); swoole_set_process_name("swoole:master {$serv->master_pid}"); echo "server start".PHP_EOL; } /** * 运行选项 * @Author bing * @DateTime 2021-10-15 11:22:58 * @copyright: Copyright (c) 2020 广东七件事集团 * @return void */ public function beforeRun(){ switch ($this->option) { case 'start': if ($this->processRunningCheck()) throw new Exception('pid 文件运行中,服务正在运行中', 500); break; case 'stop': $this->killPids(); break; case 'restart': $this->killPids(); // 等待旧进程终止 sleep(1); break; } return $this->option; } /** * 数据签名 * @Author bing * @DateTime 2021-10-18 13:20:34 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $data * @return void */ public function addSign(&$data) { asort($data); $tmpSign = serialize($data); $sign = md5($tmpSign . $this->sign); $data['sign'] = $sign; } /** * 验证签名 * @Author bing * @DateTime 2021-10-18 13:21:14 * @copyright: Copyright (c) 2020 广东七件事集团 * @param [type] $data * @return void */ public function checkSign($data) { $data = json_decode($data, true); if (!isset($data['sign'])) return false; $sign = $data['sign']; unset($data['sign']); asort($data); $tmpSign = serialize($data); $checkSign = md5($tmpSign . $this->sign); if ($checkSign == $sign) return true; return false; } }