From b611b4aad6114d0307c55c1ad5edd0c41d61d9e8 Mon Sep 17 00:00:00 2001 From: jerry Date: Fri, 29 Jan 2021 20:47:00 +0800 Subject: [PATCH] add DaemonCommand for daemon players adjust http_header available --- .gitignore | 1 + composer.json | 3 ++- config/global.php | 7 +++--- src/ZM/Command/DaemonCommand.php | 31 ++++++++++++++++++++++++++ src/ZM/Command/DaemonReloadCommand.php | 24 ++++++++++++++++++++ src/ZM/Command/DaemonStatusCommand.php | 31 ++++++++++++++++++++++++++ src/ZM/Command/DaemonStopCommand.php | 26 +++++++++++++++++++++ src/ZM/Command/RunServerCommand.php | 17 +++----------- src/ZM/ConsoleApplication.php | 7 +++++- src/ZM/Event/ServerEventHandler.php | 14 ++++++++++-- src/ZM/Framework.php | 1 + 11 files changed, 141 insertions(+), 21 deletions(-) create mode 100644 src/ZM/Command/DaemonCommand.php create mode 100644 src/ZM/Command/DaemonReloadCommand.php create mode 100644 src/ZM/Command/DaemonStatusCommand.php create mode 100644 src/ZM/Command/DaemonStopCommand.php diff --git a/.gitignore b/.gitignore index c44fa39b..d126413f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ composer.lock /bin/.phpunit.result.cache /resources/zhamao.service .phpunit.result.cache +.daemon_pid \ No newline at end of file diff --git a/composer.json b/composer.json index 64feb465..afa5fe5a 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ "zhamao/config": "^1.0", "zhamao/request": "*@dev", "symfony/routing": "^5.1", - "symfony/polyfill-php80": "^1.20" + "symfony/polyfill-php80": "^1.20", + "ext-posix": "*" }, "suggest": { "ext-ctype": "*", diff --git a/config/global.php b/config/global.php index c3f4f37d..0d3409be 100644 --- a/config/global.php +++ b/config/global.php @@ -36,13 +36,14 @@ $config['swoole'] = [ /** 轻量字符串缓存,默认开启 */ $config['light_cache'] = [ - 'size' => 1024, //最多允许储存的条数(需要2的倍数) - 'max_strlen' => 16384, //单行字符串最大长度(需要2的倍数) + 'size' => 512, //最多允许储存的条数(需要2的倍数) + 'max_strlen' => 32768, //单行字符串最大长度(需要2的倍数) 'hash_conflict_proportion' => 0.6, //Hash冲突率(越大越好,但是需要的内存更多) 'persistence_path' => $config['zm_data'].'_cache.json', 'auto_save_interval' => 900 ]; +/** 大容量跨进程变量存储(2.2.0可用) */ $config["worker_cache"] = [ "worker" => 0, "transaction_timeout" => 30000 @@ -77,7 +78,7 @@ $config["access_token"] = ''; /** HTTP服务器固定请求头的返回 */ $config['http_header'] = [ - 'X-Powered-By' => 'zhamao-framework', + 'Server' => 'zhamao-framework', 'Content-Type' => 'text/html; charset=utf-8' ]; diff --git a/src/ZM/Command/DaemonCommand.php b/src/ZM/Command/DaemonCommand.php new file mode 100644 index 00000000..6b01c7fc --- /dev/null +++ b/src/ZM/Command/DaemonCommand.php @@ -0,0 +1,31 @@ +writeln("没有检测到正在运行的守护进程!"); + die(); + } + $file = json_decode(file_get_contents($pid_path), true); + if ($file === null || posix_getsid(intval($file["pid"])) === false) { + $output->writeln("未检测到正在运行的守护进程!"); + unlink($pid_path); + die(); + } + $this->daemon_file = $file; + return Command::SUCCESS; + } +} \ No newline at end of file diff --git a/src/ZM/Command/DaemonReloadCommand.php b/src/ZM/Command/DaemonReloadCommand.php new file mode 100644 index 00000000..931c87c0 --- /dev/null +++ b/src/ZM/Command/DaemonReloadCommand.php @@ -0,0 +1,24 @@ +setDescription("重载守护进程下的用户代码(仅限--daemon模式可用)"); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + parent::execute($input, $output); + system("kill -USR1 " . intval($this->daemon_file["pid"])); + $output->writeln("成功重载!"); + return Command::SUCCESS; + } +} diff --git a/src/ZM/Command/DaemonStatusCommand.php b/src/ZM/Command/DaemonStatusCommand.php new file mode 100644 index 00000000..28201383 --- /dev/null +++ b/src/ZM/Command/DaemonStatusCommand.php @@ -0,0 +1,31 @@ +setDescription("查看守护进程框架的运行状态(仅限--daemon模式可用)"); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + parent::execute($input, $output); + $output->writeln("框架运行中,pid:" . $this->daemon_file["pid"] . ""); + $output->writeln("----- 以下是stdout内容 -----"); + $stdout = file_get_contents($this->daemon_file["stdout"]); + $stdout = explode("\n", $stdout); + for ($i = 10; $i > 0; --$i) { + if (isset($stdout[count($stdout) - $i])) + echo $stdout[count($stdout) - $i] . PHP_EOL; + } + return Command::SUCCESS; + } +} diff --git a/src/ZM/Command/DaemonStopCommand.php b/src/ZM/Command/DaemonStopCommand.php new file mode 100644 index 00000000..754965b3 --- /dev/null +++ b/src/ZM/Command/DaemonStopCommand.php @@ -0,0 +1,26 @@ +setDescription("停止守护进程下运行的框架(仅限--daemon模式可用)"); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + parent::execute($input, $output); + system("kill -TERM ".intval($this->daemon_file["pid"])); + unlink(DataProvider::getWorkingDir()."/.daemon_pid"); + $output->writeln("成功停止!"); + return Command::SUCCESS; + } +} diff --git a/src/ZM/Command/RunServerCommand.php b/src/ZM/Command/RunServerCommand.php index 639b6091..926c96a6 100644 --- a/src/ZM/Command/RunServerCommand.php +++ b/src/ZM/Command/RunServerCommand.php @@ -11,7 +11,6 @@ use ZM\Framework; class RunServerCommand extends Command { - // the name of the command (the part after "bin/console") protected static $defaultName = 'server'; protected function configure() { @@ -31,27 +30,17 @@ class RunServerCommand extends Command ]); $this->setDescription("Run zhamao-framework | 启动框架"); $this->setHelp("直接运行可以启动"); - - // ... } protected function execute(InputInterface $input, OutputInterface $output) { - if(($opt = $input->getOption("env")) !== null) { - if(!in_array($opt, ["production", "staging", "development", ""])) { + if (($opt = $input->getOption("env")) !== null) { + if (!in_array($opt, ["production", "staging", "development", ""])) { $output->writeln(" \"--env\" option only accept production, development, staging and [empty] ! "); return Command::FAILURE; } } - // ... put here the code to run in your command - // this method must return an integer number with the "exit status code" - // of the command. You can also use these constants to make code more readable + if (LOAD_MODE == 0) echo "* This is repository mode.\n"; (new Framework($input->getOptions()))->start(); - // return this if there was no problem running the command - // (it's equivalent to returning int(0)) return Command::SUCCESS; - - // or return this if some error happened during the execution - // (it's equivalent to returning int(1)) - // return Command::FAILURE; } } diff --git a/src/ZM/ConsoleApplication.php b/src/ZM/ConsoleApplication.php index 748a76ae..e190d9ff 100644 --- a/src/ZM/ConsoleApplication.php +++ b/src/ZM/ConsoleApplication.php @@ -5,6 +5,9 @@ namespace ZM; use Exception; +use ZM\Command\DaemonReloadCommand; +use ZM\Command\DaemonStatusCommand; +use ZM\Command\DaemonStopCommand; use ZM\Command\InitCommand; use ZM\Command\PureHttpCommand; use ZM\Command\RunServerCommand; @@ -40,7 +43,6 @@ class ConsoleApplication extends Application * @noinspection RedundantSuppression */ require_once WORKING_DIR . "/vendor/autoload.php"; - echo "* This is repository mode.\n"; $composer = json_decode(file_get_contents(DataProvider::getWorkingDir() . "/composer.json"), true); if (!isset($composer["autoload"]["psr-4"]["Module\\"])) { echo "框架源码模式需要在autoload文件中添加Module目录为自动加载,是否添加?[Y/n] "; @@ -64,6 +66,9 @@ class ConsoleApplication extends Application } $this->addCommands([ + new DaemonStatusCommand(), + new DaemonReloadCommand(), + new DaemonStopCommand(), new RunServerCommand(), //运行主服务的指令控制器 new InitCommand(), //初始化用的,用于项目初始化和phar初始化 new PureHttpCommand() //纯HTTP服务器指令 diff --git a/src/ZM/Event/ServerEventHandler.php b/src/ZM/Event/ServerEventHandler.php index 9df85e5b..72786b9e 100644 --- a/src/ZM/Event/ServerEventHandler.php +++ b/src/ZM/Event/ServerEventHandler.php @@ -79,6 +79,13 @@ class ServerEventHandler /** @noinspection PhpUndefinedFieldInspection */ Event::del(Framework::$server->inotify); ZMUtil::stop(); }); + if(Framework::$argv["daemon"]) { + $daemon_data = json_encode([ + "pid" => \server()->master_pid, + "stdout" => ZMConfig::get("global")["swoole"]["log_file"] + ],128|256); + file_put_contents(DataProvider::getWorkingDir()."/.daemon_pid", $daemon_data); + } if (Framework::$argv["watch"]) { if (extension_loaded('inotify')) { Console::warning("Enabled File watcher, do not use in production."); @@ -87,11 +94,11 @@ class ServerEventHandler $this->addWatcher(DataProvider::getWorkingDir() . "/src", $fd); Event::add($fd, function () use ($fd) { $r = inotify_read($fd); - var_dump($r); + dump($r); ZMUtil::reload(); }); } else { - Console::warning("You have not loaded inotify extension."); + Console::warning("You have not loaded \"inotify\" extension, please install first."); } } } @@ -307,6 +314,9 @@ class ServerEventHandler */ public function onRequest(?Request $request, ?\Swoole\Http\Response $response) { $response = new Response($response); + foreach(ZMConfig::get("global")["http_header"] as $k => $v) { + $response->setHeader($k, $v); + } unset(Context::$context[Co::getCid()]); Console::debug("Calling Swoole \"request\" event from fd=" . $request->fd); set_coroutine_params(["request" => $request, "response" => $response]); diff --git a/src/ZM/Framework.php b/src/ZM/Framework.php index 5698eebf..b3a64ef9 100644 --- a/src/ZM/Framework.php +++ b/src/ZM/Framework.php @@ -250,6 +250,7 @@ class Framework case 'daemon': if ($y) { $this->server_set["daemonize"] = 1; + Console::$theme = "no-color"; Console::log("已启用守护进程,输出重定向到 " . $this->server_set["log_file"]); $terminal_id = null; }