add DaemonCommand for daemon players

adjust http_header available
This commit is contained in:
jerry 2021-01-29 20:47:00 +08:00
parent b9f973c718
commit b611b4aad6
11 changed files with 141 additions and 21 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ composer.lock
/bin/.phpunit.result.cache
/resources/zhamao.service
.phpunit.result.cache
.daemon_pid

View File

@ -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": "*",

View File

@ -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'
];

View File

@ -0,0 +1,31 @@
<?php
namespace ZM\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use ZM\Utils\DataProvider;
abstract class DaemonCommand extends Command
{
protected $daemon_file = null;
protected function execute(InputInterface $input, OutputInterface $output) {
$pid_path = DataProvider::getWorkingDir() . "/.daemon_pid";
if (!file_exists($pid_path)) {
$output->writeln("<comment>没有检测到正在运行的守护进程!</comment>");
die();
}
$file = json_decode(file_get_contents($pid_path), true);
if ($file === null || posix_getsid(intval($file["pid"])) === false) {
$output->writeln("<comment>未检测到正在运行的守护进程!</comment>");
unlink($pid_path);
die();
}
$this->daemon_file = $file;
return Command::SUCCESS;
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace ZM\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class DaemonReloadCommand extends DaemonCommand
{
protected static $defaultName = 'daemon:reload';
protected function configure() {
$this->setDescription("重载守护进程下的用户代码(仅限--daemon模式可用");
}
protected function execute(InputInterface $input, OutputInterface $output) {
parent::execute($input, $output);
system("kill -USR1 " . intval($this->daemon_file["pid"]));
$output->writeln("<info>成功重载!</info>");
return Command::SUCCESS;
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace ZM\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use ZM\Utils\DataProvider;
class DaemonStatusCommand extends DaemonCommand
{
protected static $defaultName = 'daemon:status';
protected function configure() {
$this->setDescription("查看守护进程框架的运行状态(仅限--daemon模式可用");
}
protected function execute(InputInterface $input, OutputInterface $output) {
parent::execute($input, $output);
$output->writeln("<info>框架运行中pid" . $this->daemon_file["pid"] . "</info>");
$output->writeln("<comment>----- 以下是stdout内容 -----</comment>");
$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;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace ZM\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use ZM\Utils\DataProvider;
class DaemonStopCommand extends DaemonCommand
{
protected static $defaultName = 'daemon:stop';
protected function configure() {
$this->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("<info>成功停止!</info>");
return Command::SUCCESS;
}
}

View File

@ -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("<error> \"--env\" option only accept production, development, staging and [empty] ! </error>");
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;
}
}

View File

@ -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服务器指令

View File

@ -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]);

View File

@ -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;
}