Skip to content
This repository has been archived by the owner on Nov 2, 2020. It is now read-only.

Commit

Permalink
perf(Config): Create \Swoole\Table as Dynamic Config Provider in Mast…
Browse files Browse the repository at this point in the history
…er Process

Before this commit, The DynamicConfig Provider \swoole_table will create
on each Worker process, and it's value will not share cross the process.
  • Loading branch information
Rhilip committed Feb 8, 2019
1 parent 4799813 commit 0a7bfba
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 90 deletions.
31 changes: 10 additions & 21 deletions apps/commands/ServiceCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,10 @@
class ServiceCommand extends Command
{

// 是否后台运行
public $daemon = false;
public $daemon = false; // 是否后台运行
public $update = false; // 是否热更新

// 是否热更新
public $update = false;

// PID 文件
protected $pidFile;
protected $pidFile; // PID 文件

// 选项配置
public function options()
Expand All @@ -37,8 +33,7 @@ public function optionAliases()
public function onInitialize()
{
parent::onInitialize();
// 设置pidfile
$this->pidFile = '/var/run/rid-httpd.pid';
$this->pidFile = '/var/run/rid-httpd.pid'; // 设置pidfile
}

// 启动服务
Expand All @@ -55,8 +50,7 @@ public function actionStart()
$server->settings['daemonize'] = $this->daemon;
$server->settings['pid_file'] = $this->pidFile;
$server->start();
// 返回退出码
return ExitCode::OK;
return ExitCode::OK; // 返回退出码
}

// 停止服务
Expand All @@ -65,24 +59,21 @@ public function actionStop()
if ($pid = ProcessHelper::readPidFile($this->pidFile)) {
ProcessHelper::kill($pid);
while (ProcessHelper::isRunning($pid)) {
// 等待进程退出
usleep(100000);
usleep(100000); // 等待进程退出
}
println('rid-httpd stop completed.');
} else {
println('rid-httpd is not running.');
}
// 返回退出码
return ExitCode::OK;
return ExitCode::OK; // 返回退出码
}

// 重启服务
public function actionRestart()
{
$this->actionStop();
$this->actionStart();
// 返回退出码
return ExitCode::OK;
return ExitCode::OK; // 返回退出码
}

// 重启工作进程
Expand All @@ -96,8 +87,7 @@ public function actionReload()
return ExitCode::UNSPECIFIED_ERROR;
}
println('rid-httpd worker process restart completed.');
// 返回退出码
return ExitCode::OK;
return ExitCode::OK; // 返回退出码
}

// 查看服务状态
Expand All @@ -108,8 +98,7 @@ public function actionStatus()
} else {
println('rid-httpd is not running.');
}
// 返回退出码
return ExitCode::OK;
return ExitCode::OK; // 返回退出码
}

}
31 changes: 11 additions & 20 deletions apps/config/httpd.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@
// HttpServer
'httpServer' => [

// 类路径
'class' => Rid\Http\HttpServer::class,
'class' => Rid\Http\HttpServer::class, // 类路径

// 虚拟主机:运行在服务器内的 HTTP 服务
'virtualHost' => [
Expand All @@ -60,24 +59,16 @@

// 运行参数:https://wiki.swoole.com/wiki/page/274.html
'settings' => [
// 开启协程
'enable_coroutine' => false,
// 连接处理线程数
'reactor_num' => 1,
// 工作进程数
'worker_num' => 20,
// PID 文件
'pid_file' => '/var/run/rid-httpd.pid',
// 日志文件路径
'log_file' => '/tmp/rid-httpd.log',
// 进程的最大任务数
'max_request' => 3000,
// 退出等待时间
'max_wait_time' => 60,
// 异步安全重启
'reload_async' => true,
// 子进程运行用户
/* 'user' => 'www', */
'enable_coroutine' => false, // 开启协程
'reactor_num' => 1, // 连接处理线程数
'worker_num' => 20, // 工作进程数
'pid_file' => '/var/run/rid-httpd.pid', // PID 文件
'log_file' => '/tmp/rid-httpd.log', // 日志文件路径
'max_request' => 3000, // 进程的最大任务数
'max_wait_time' => 60, // 退出等待时间
'package_max_length' => 6242880, // 最大上传包大小,单位 Bytes
'reload_async' => true, // 异步安全重启
/* 'user' => 'www', // 子进程运行用户 */
],

],
Expand Down
11 changes: 11 additions & 0 deletions apps/middleware/AfterMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ public function handle($callable, \Closure $next)
// 添加中间件执行代码
$response = $next();
list($controller, $action) = $callable;

if (env('APP_DEBUG')) {
println('NOW() :' . date('Y-m-d H:i:s')) ;
echo 'SQL query list: ';
var_dump(app()->pdo->getExecuteData());
echo 'Redis Hits: ';
var_dump(app()->redis->getCalledData());
echo 'Memory used: ';
var_dump(memory_get_usage());
}

// ...
// 返回响应内容
return $response;
Expand Down
2 changes: 0 additions & 2 deletions apps/models/form/TorrentUploadForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,6 @@ public function flush()
app()->pdo->rollback();

throw $e;
} finally {
unlink($this->file->getPathname()); // Remove temp file
}
}

Expand Down
4 changes: 1 addition & 3 deletions framework/Config/ConfigByRedis.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@ class ConfigByRedis extends Component implements DynamicConfigInterface

public $cacheExpire = 86400;

public function __construct(array $config = [])
public function onInitialize(array $config = [])
{
parent::__construct($config);

if (!app()->redis->exists($this->cacheField)) {
$configs_pdo = app()->pdo->createCommand("SELECT `name`,`value` FROM `site_config`")->queryAll();
$configs = array_column($configs_pdo, 'value', 'name');
Expand Down
20 changes: 10 additions & 10 deletions framework/Config/ConfigBySwoole.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ class ConfigBySwoole extends Component implements DynamicConfigInterface
private $cacheTable;
private $valueField = 'data';

public function __construct(array $config = [])
public function onInitialize(array $config = [])
{
parent::__construct($config);
// Get \Swoole\Table object From \Server, So that we can share same dynamic config
$this->cacheTable = app()->getServ()->configTable;

$this->cacheTable = new \Swoole\Table(2048);

$this->cacheTable->column($this->valueField, \Swoole\Table::TYPE_STRING, 256);
$this->cacheTable->create();

$configs = app()->pdo->createCommand("SELECT `name`,`value` FROM `site_config`")->queryAll();
foreach ($configs as $config) {
$this->cacheTable->set($config["name"], [$this->valueField => $config["value"]]);
// If empty Config Table and this component get construct Lock
if ($this->cacheTable->count() == 0 && app()->getServ()->configTable_construct_lock->trylock()) {
$configs = app()->pdo->createCommand("SELECT `name`,`value` FROM `site_config`")->queryAll();
foreach ($configs as $config) {
$this->cacheTable->set($config["name"], [$this->valueField => $config["value"]]);
}
app()->getServ()->configTable_construct_lock->unlock();
}
}

Expand Down
2 changes: 1 addition & 1 deletion framework/Helpers/ProcessHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ProcessHelper
// 使当前进程蜕变为一个守护进程
public static function daemon($closeStandardInputOutput = true)
{
return \Swoole\Process::daemon(true, !$closeStandardInputOutput);
\Swoole\Process::daemon(true, !$closeStandardInputOutput);
}

// 设置进程标题
Expand Down
43 changes: 41 additions & 2 deletions framework/Http/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class Application extends \Rid\Base\Application
// 是否为协程环境
protected $_isCoroutine;

protected $_serv;
protected $_worker;

// 初始化事件
public function onInitialize()
{
Expand Down Expand Up @@ -186,15 +189,19 @@ public function cleanComponents()
}
}

// 触发请求前置事件
/** 触发请求前置事件
* @param \Rid\Base\Component $component
*/
protected function triggerRequestBefore($component)
{
if ($component->getStatus() == Component::STATUS_READY) {
$component->onRequestBefore();
}
}

// 触发请求后置事件
/** 触发请求后置事件
* @param \Rid\Base\Component $component
*/
protected function triggerRequestAfter($component)
{
if ($component->getStatus() == Component::STATUS_RUNNING) {
Expand Down Expand Up @@ -237,4 +244,36 @@ public function end($content = '')
throw new \Rid\Exceptions\EndException($content);
}

/**
* @return mixed
*/
public function getServ()
{
return $this->_serv;
}

/**
* @param mixed $serv
*/
public function setServ($serv): void
{
$this->_serv = $serv;
}

/**
* @return mixed
*/
public function getWorker()
{
return $this->_worker;
}

/**
* @param mixed $worker
*/
public function setWorker($worker): void
{
$this->_worker = $worker;
}

}
66 changes: 35 additions & 31 deletions framework/Http/HttpServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,16 @@ class HttpServer extends BaseObject

// 默认运行参数
protected $_settings = [
// 开启协程
'enable_coroutine' => false,
// 主进程事件处理线程数
'reactor_num' => 8,
// 工作进程数
'worker_num' => 8,
// 任务进程数
'task_worker_num' => 0,
// 进程的最大任务数
'max_request' => 10000,
// 异步安全重启
'reload_async' => true,
// 退出等待时间
'max_wait_time' => 60,
// PID 文件
'pid_file' => '/var/run/rid-httpd.pid',
// 日志文件路径
'log_file' => '/tmp/rid-httpd.log',
// 开启后,PDOConnection 协程多次 prepare 才不会有 40ms 延迟
'open_tcp_nodelay' => true,
'enable_coroutine' => false, // 开启协程
'reactor_num' => 8, // 主进程事件处理线程数
'worker_num' => 8, // 工作进程数
'task_worker_num' => 0, // 任务进程数
'max_request' => 10000, // 进程的最大任务数
'reload_async' => true, // 异步安全重启
'max_wait_time' => 60, // 退出等待时间
'pid_file' => '/var/run/rid-httpd.pid', // PID 文件
'log_file' => '/tmp/rid-httpd.log', // 日志文件路径
'open_tcp_nodelay' => true, // 开启后,PDOConnection 协程多次 prepare 才不会有 40ms 延迟
];

// 服务器
Expand All @@ -59,8 +49,7 @@ protected function initialize()
$this->_host = $this->virtualHost['host'];
$this->_port = $this->virtualHost['port'];
$this->settings += $this->_settings;
// 实例化服务器
$this->_server = new \Swoole\Http\Server($this->_host, $this->_port);
$this->createSever();
}

// 启动服务
Expand All @@ -79,16 +68,15 @@ public function start()
// 主进程启动事件
protected function onStart()
{
$this->_server->on('Start', function ($server) {
// 进程命名
$this->_server->on('Start', function (\swoole_server $server) {
ProcessHelper::setTitle("rid-httpd: master {$this->_host}:{$this->_port}");
});
}

// 管理进程启动事件
protected function onManagerStart()
{
$this->_server->on('ManagerStart', function ($server) {
$this->_server->on('ManagerStart', function (\swoole_server $server) {
// 进程命名
ProcessHelper::setTitle("rid-httpd: manager");
});
Expand All @@ -97,7 +85,7 @@ protected function onManagerStart()
// 工作进程启动事件
protected function onWorkerStart()
{
$this->_server->on('WorkerStart', function ($server, $workerId) {
$this->_server->on('WorkerStart', function (\swoole_server $server,int $workerId) {
// 进程命名
if ($workerId < $server->setting['worker_num']) {
ProcessHelper::setTitle("rid-httpd: worker #{$workerId}");
Expand All @@ -107,25 +95,41 @@ protected function onWorkerStart()
// 实例化App
$config = require $this->virtualHost['configFile'];
$app = new Application($config);
$app->setServ($this->_server);
$app->setWorker($workerId);
$app->loadAllComponents();
});
}

// 请求事件
protected function onRequest()
{
$this->_server->on('request', function ($request, $response) {
$this->_server->on('request', function (\swoole_http_request $request,\swoole_http_response $response) {
// 执行请求
try {
\Rid::app()->request->setRequester($request);
\Rid::app()->response->setResponder($response);
\Rid::app()->run();
app()->request->setRequester($request);
app()->response->setResponder($response);
app()->run();
} catch (\Throwable $e) {
\Rid::app()->error->handleException($e);
app()->error->handleException($e);
}
});
}

protected function createSever() {
// 实例化服务器
$this->_server = new \Swoole\Http\Server($this->_host, $this->_port);

// rid-httpd 模式下,ConfigHandler 一定为 \Swoole\Table ,在此处创建全局的 \Swoole\Table
$configTable = new \Swoole\Table(2048);
$configTable->column('data', \Swoole\Table::TYPE_STRING, 256);
$configTable->create();
$this->_server->configTable = $configTable;

// 为 Dynamic Config construct行为创建一个锁,防止不同Worker下的Config同时写入(虽然这种情况也没什么事)
$this->_server->configTable_construct_lock = new \Swoole\Lock(SWOOLE_MUTEX);
}

// 欢迎信息
protected function welcome()
{
Expand Down

0 comments on commit 0a7bfba

Please sign in to comment.