1
This commit is contained in:
@@ -1,115 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace db;
|
|
||||||
|
|
||||||
use database\seeders\SeedManager;
|
|
||||||
use think\console\Command;
|
|
||||||
use think\console\Input;
|
|
||||||
use think\console\input\Argument;
|
|
||||||
use think\console\Output;
|
|
||||||
use think\console\input\Option;
|
|
||||||
use think\facade\Db;
|
|
||||||
|
|
||||||
class DatabaseManage extends Command
|
|
||||||
{
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
$this->setName('db:manage')
|
|
||||||
->addArgument('action', \think\console\input\Argument::OPTIONAL, 'The action to perform: backup or init or seed')
|
|
||||||
->setDescription('Manage the database: backup or initialize');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(Input $input, Output $Output)
|
|
||||||
{
|
|
||||||
$strAction = $input->getArgument('action');
|
|
||||||
|
|
||||||
if ($strAction === 'backup') {
|
|
||||||
$this->backupDatabase($Output);
|
|
||||||
} elseif ($strAction === 'init') {
|
|
||||||
$this->initializeDatabase($Output);
|
|
||||||
} elseif ($strAction === 'seed') {
|
|
||||||
$this->seed($Output);
|
|
||||||
} else {
|
|
||||||
$Output->writeln("Invalid action. Use 'backup' or 'init'. or 'seed'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function seed(Output $Output)
|
|
||||||
{
|
|
||||||
$SeedManager = new SeedManager;
|
|
||||||
$Output->writeln("开始数据播种" . PHP_EOL);
|
|
||||||
$SeedManager->handle();
|
|
||||||
$Output->writeln("数据播种结束");
|
|
||||||
}
|
|
||||||
|
|
||||||
private function backupDatabase(Output $Output)
|
|
||||||
{
|
|
||||||
$arrConfig = config('database.connections.mysql');
|
|
||||||
$strDb = $arrConfig['database'];
|
|
||||||
$strUserName = $arrConfig['username'];
|
|
||||||
$strPwd = $arrConfig['password'];
|
|
||||||
$strHost = $arrConfig['hostname'];
|
|
||||||
$strBackupFile = app()->getRootPath() . 'database/schema/mysql-schema.dump';
|
|
||||||
|
|
||||||
$strTempFile = tempnam(sys_get_temp_dir(), 'mysql-schema-') . '.dump';
|
|
||||||
|
|
||||||
$strCmd = "mysqldump -h{$strHost} -u{$strUserName} -p{$strPwd} --no-data {$strDb} > {$strTempFile}";
|
|
||||||
|
|
||||||
system($strCmd, $intResultCode);
|
|
||||||
|
|
||||||
if ($intResultCode === 0) {
|
|
||||||
if (file_exists($strBackupFile)) {
|
|
||||||
unlink($strBackupFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rename($strTempFile, $strBackupFile)) {
|
|
||||||
$Output->writeln("Database backup successful: {$strBackupFile}");
|
|
||||||
} else {
|
|
||||||
$Output->writeln("Failed to move backup file to destination.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$Output->writeln("Database backup failed.");
|
|
||||||
unlink($strTempFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function initializeDatabase(Output $Output)
|
|
||||||
{
|
|
||||||
$arrConfig = config('database.connections.mysql');
|
|
||||||
$strDb = $arrConfig['database'];
|
|
||||||
$strUserName = $arrConfig['username'];
|
|
||||||
$strPwd = $arrConfig['password'];
|
|
||||||
$strHost = $arrConfig['hostname'];
|
|
||||||
$strPort = $arrConfig['hostport'];
|
|
||||||
$strBackupFile = app()->getRootPath() . 'database/schema/mysql-schema.dump';
|
|
||||||
|
|
||||||
$checkTableQuery = "SHOW TABLES LIKE 'migrations'";
|
|
||||||
$boolMigrateExists = Db::query($checkTableQuery);
|
|
||||||
|
|
||||||
if (!empty($boolMigrateExists)) {
|
|
||||||
$Output->writeln("数据库已存在,跳过初始化导入");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$strTempFile = tempnam(sys_get_temp_dir(), 'mysql-schema-') . '.dump';
|
|
||||||
|
|
||||||
if (!copy($strBackupFile, $strTempFile)) {
|
|
||||||
$Output->writeln("创建临时导入文件失败.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$strCmd = "mysql -h{$strHost} -P{$strPort} -u{$strUserName} -p{$strPwd} {$strDb} < {$strTempFile}";
|
|
||||||
|
|
||||||
system($strCmd, $intResultCode);
|
|
||||||
|
|
||||||
if ($intResultCode === 0) {
|
|
||||||
$Output->writeln("成功导入初始化文件");
|
|
||||||
} else {
|
|
||||||
$Output->writeln("初始化文件导入失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
unlink($strTempFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,191 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace db\mongo;
|
|
||||||
|
|
||||||
use MongoDB\Client;
|
|
||||||
use MongoDB\Exception\Exception as MongoDBException;
|
|
||||||
use MongoDB\BSON\UTCDateTime;
|
|
||||||
|
|
||||||
class MongoBase
|
|
||||||
{
|
|
||||||
private $client;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Undocumented variable
|
|
||||||
*
|
|
||||||
* @var \MongoDB\Database
|
|
||||||
*/
|
|
||||||
private $db;
|
|
||||||
|
|
||||||
private static $instance;
|
|
||||||
|
|
||||||
public static function getInstance(): self
|
|
||||||
{
|
|
||||||
|
|
||||||
// return [
|
|
||||||
// 'uri' => 'mongodb://username:password@your_ip:27017',
|
|
||||||
// 'database' => 'your_database',
|
|
||||||
// ];
|
|
||||||
|
|
||||||
if (!self::$instance) {
|
|
||||||
self::$instance = new self();
|
|
||||||
}
|
|
||||||
return self::$instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构造函数,初始化 MongoDB 连接
|
|
||||||
* @param string $uri MongoDB 连接字符串
|
|
||||||
* @param string $dbName 数据库名称
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$arrConfig = config('mongodb');
|
|
||||||
$strUri = sprintf('mongodb://%s:%s@%s:%s', $arrConfig['username'], $arrConfig['password'], $arrConfig['hostname'], $arrConfig['hostport']);
|
|
||||||
|
|
||||||
$this->client = new Client($strUri);
|
|
||||||
$this->db = $this->client->selectDatabase($arrConfig['database']);
|
|
||||||
} catch (MongoDBException $e) {
|
|
||||||
throw new \Exception("MongoDB connection failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取下一个自增序列值
|
|
||||||
* @param string $sequenceName 序列名称
|
|
||||||
* @return int 自增 ID
|
|
||||||
*/
|
|
||||||
public function getNextSequence(string $sequenceName): int
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$counters = $this->db->selectCollection('counters');
|
|
||||||
$result = $counters->findOneAndUpdate(
|
|
||||||
['_id' => $sequenceName],
|
|
||||||
['$inc' => ['sequence_value' => 1]],
|
|
||||||
[
|
|
||||||
'upsert' => true,
|
|
||||||
'returnDocument' => \MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER
|
|
||||||
]
|
|
||||||
);
|
|
||||||
return $result->sequence_value ?? 1;
|
|
||||||
} catch (MongoDBException $e) {
|
|
||||||
throw new \Exception("Failed to generate sequence: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插入单条数据
|
|
||||||
* @param string $collection 集合名称
|
|
||||||
* @param array $data 数据数组
|
|
||||||
* @return mixed 插入的 ID
|
|
||||||
*/
|
|
||||||
public function insertOne(string $collection, array $data)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$coll = $this->db->selectCollection($collection);
|
|
||||||
$data['created_at'] = new UTCDateTime(); // 自动添加创建时间
|
|
||||||
$result = $coll->insertOne($data);
|
|
||||||
return $result->getInsertedId();
|
|
||||||
} catch (MongoDBException $e) {
|
|
||||||
throw new \Exception("Insert failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getDb(): \MongoDB\Database
|
|
||||||
{
|
|
||||||
return $this->db;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插入多条数据
|
|
||||||
* @param string $collection 集合名称
|
|
||||||
* @param array $data 多条数据数组
|
|
||||||
* @return array 插入的 ID 列表
|
|
||||||
*/
|
|
||||||
public function insertMany(string $collection, array $data)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$coll = $this->db->selectCollection($collection);
|
|
||||||
foreach ($data as &$item) {
|
|
||||||
$item['created_at'] = new UTCDateTime();
|
|
||||||
}
|
|
||||||
$result = $coll->insertMany($data);
|
|
||||||
return $result->getInsertedIds();
|
|
||||||
} catch (MongoDBException $e) {
|
|
||||||
throw new \Exception("Insert many failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询单条数据
|
|
||||||
* @param string $collection 集合名称
|
|
||||||
* @param array $filter 查询条件
|
|
||||||
* @param array $options 查询选项
|
|
||||||
* @return ?object 查询结果
|
|
||||||
*/
|
|
||||||
public function findOne(string $collection, array $filter = [], array $options = []): ?object
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$coll = $this->db->selectCollection($collection);
|
|
||||||
return $coll->findOne($filter, $options);
|
|
||||||
} catch (MongoDBException $e) {
|
|
||||||
throw new \Exception("Find one failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询多条数据
|
|
||||||
* @param string $collection 集合名称
|
|
||||||
* @param array $filter 查询条件
|
|
||||||
* @param array $options 查询选项
|
|
||||||
* @return array 查询结果
|
|
||||||
*/
|
|
||||||
public function findMany(string $collection, array $filter = [], array $options = []): array
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$coll = $this->db->selectCollection($collection);
|
|
||||||
$cursor = $coll->find($filter, $options);
|
|
||||||
return iterator_to_array($cursor);
|
|
||||||
} catch (MongoDBException $e) {
|
|
||||||
throw new \Exception("Find many failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新单条数据
|
|
||||||
* @param string $collection 集合名称
|
|
||||||
* @param array $filter 查询条件
|
|
||||||
* @param array $update 更新内容
|
|
||||||
* @param array $options 更新选项
|
|
||||||
* @return int 受影响的文档数
|
|
||||||
*/
|
|
||||||
public function updateOne(string $collection, array $filter, array $update, array $options = []): int
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$coll = $this->db->selectCollection($collection);
|
|
||||||
$update['$set']['updated_at'] = new UTCDateTime(); // 自动添加更新时间
|
|
||||||
$result = $coll->updateOne($filter, $update, $options);
|
|
||||||
return $result->getModifiedCount();
|
|
||||||
} catch (MongoDBException $e) {
|
|
||||||
throw new \Exception("Update one failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除数据
|
|
||||||
* @param string $collection 集合名称
|
|
||||||
* @param array $filter 查询条件
|
|
||||||
* @return int 删除的文档数
|
|
||||||
*/
|
|
||||||
public function delete(string $collection, array $filter): int
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
$coll = $this->db->selectCollection($collection);
|
|
||||||
$result = $coll->deleteMany($filter);
|
|
||||||
return $result->getDeletedCount();
|
|
||||||
} catch (MongoDBException $e) {
|
|
||||||
throw new \Exception("Delete failed: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
66
code/extend/ddl/DDLManage.php
Normal file
66
code/extend/ddl/DDLManage.php
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace ddl;
|
||||||
|
|
||||||
|
class DDLManage
|
||||||
|
{
|
||||||
|
private static $arrLoadedModules = [];
|
||||||
|
|
||||||
|
private static $arrModuleFiles = [
|
||||||
|
'MicroServer' => 'extend/ddl/MicroCore.ddl',
|
||||||
|
'MongoBase' => 'extend/ddl/MongoBase.ddl',
|
||||||
|
'DatabaseManage' => 'extend/ddl/DatabaseManage.ddl',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载指定模块
|
||||||
|
* @param string $strModuleCode 模块编码
|
||||||
|
* @return bool 加载是否成功
|
||||||
|
*/
|
||||||
|
public static function load($strModuleCode)
|
||||||
|
{
|
||||||
|
if (isset(self::$arrLoadedModules[$strModuleCode])) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset(self::$arrModuleFiles[$strModuleCode])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = self::$arrModuleFiles[$strModuleCode];
|
||||||
|
|
||||||
|
$strFileName = root_path() . $filename;
|
||||||
|
|
||||||
|
if (!file_exists($strFileName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (load_module_file($strFileName)) {
|
||||||
|
self::$arrLoadedModules[$strModuleCode] = true;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查模块是否已加载
|
||||||
|
* @param string $strModuleCode 类名
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isLoaded($strModuleCode)
|
||||||
|
{
|
||||||
|
return isset(self::$arrLoadedModules[$strModuleCode]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有已加载的模块
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function getarrLoadedModules()
|
||||||
|
{
|
||||||
|
return array_keys(self::$arrLoadedModules);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
code/extend/ddl/DatabaseManage.ddl
Normal file
BIN
code/extend/ddl/DatabaseManage.ddl
Normal file
Binary file not shown.
BIN
code/extend/ddl/MicroCore.ddl
Normal file
BIN
code/extend/ddl/MicroCore.ddl
Normal file
Binary file not shown.
BIN
code/extend/ddl/MongoBase.ddl
Normal file
BIN
code/extend/ddl/MongoBase.ddl
Normal file
Binary file not shown.
@@ -1,302 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace microserver;
|
|
||||||
|
|
||||||
use think\Container;
|
|
||||||
use think\facade\Db;
|
|
||||||
use think\facade\Cache;
|
|
||||||
|
|
||||||
class ProcessSanitizer
|
|
||||||
{
|
|
||||||
static public function reloadRedis()
|
|
||||||
{
|
|
||||||
Container::getInstance()->delete('cache');
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function reloadDb()
|
|
||||||
{
|
|
||||||
Db::close();
|
|
||||||
Container::getInstance()->delete('think\DbManager');
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function destructConnectSource()
|
|
||||||
{
|
|
||||||
self::reloadDb();
|
|
||||||
self::reloadRedis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class QueueManage
|
|
||||||
{
|
|
||||||
public $strQueueName = '';
|
|
||||||
|
|
||||||
static private $arrObj = [];
|
|
||||||
|
|
||||||
static public function getInstance($intIndex = 1, $strQueueName = '')
|
|
||||||
{
|
|
||||||
$strKey = $intIndex . '-' . $strQueueName;
|
|
||||||
|
|
||||||
if (!key_exists($strKey, self::$arrObj)) {
|
|
||||||
self::$arrObj[$strKey] = new self($intIndex, $strQueueName);
|
|
||||||
}
|
|
||||||
return self::$arrObj[$strKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct($intIndex = 1, $strQueueName = '')
|
|
||||||
{
|
|
||||||
if ($strQueueName == '') {
|
|
||||||
$arrConfig = config('task.queue');
|
|
||||||
$strQueueName = $arrConfig[$intIndex]['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->strQueueName = $strQueueName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get()
|
|
||||||
{
|
|
||||||
return Cache::store('redis')->lpop($this->strQueueName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($arrData)
|
|
||||||
{
|
|
||||||
$strData = json_encode($arrData);
|
|
||||||
return Cache::store('redis')->rpush($this->strQueueName, $strData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Rout
|
|
||||||
{
|
|
||||||
static public function httpDispense(\Swoole\Http\Request $Request, \Swoole\Http\Response $Response)
|
|
||||||
{
|
|
||||||
$Response->status(999, 'Hei Guys ~');
|
|
||||||
$Response->header("Content-Type", "text/html; charset=utf-8");
|
|
||||||
$Response->end("<h1>Hello reptile~. #" . rand(1000, 9999) . "</h1>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function tcpDispense(\Swoole\Server $server, $fd, $reactor_id, $mixedData) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ScheduledTasks
|
|
||||||
{
|
|
||||||
static public function hander($arrProcessTask = [])
|
|
||||||
{
|
|
||||||
ProcessSanitizer::destructConnectSource();
|
|
||||||
|
|
||||||
call_user_func($arrProcessTask['callback'], $arrProcessTask['param']);
|
|
||||||
|
|
||||||
sleep($arrProcessTask['execution_interval']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ServerCore
|
|
||||||
{
|
|
||||||
private $arrConfig;
|
|
||||||
|
|
||||||
private static $obj;
|
|
||||||
|
|
||||||
private $Server;
|
|
||||||
|
|
||||||
static $Process = NULL;
|
|
||||||
|
|
||||||
static function instance($arrConfig)
|
|
||||||
{
|
|
||||||
if (self::$obj == null) {
|
|
||||||
self::$obj = new self($arrConfig);
|
|
||||||
}
|
|
||||||
return self::$obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct($arrConfig)
|
|
||||||
{
|
|
||||||
$this->arrConfig = $arrConfig;
|
|
||||||
$this->createServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function serHttpConfig()
|
|
||||||
{
|
|
||||||
$this->Server->set($this->filterConfig());
|
|
||||||
$this->Server->on('request', [Rout::class, 'httpDispense']);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function filterConfig()
|
|
||||||
{
|
|
||||||
$arrConfig = $this->arrConfig;
|
|
||||||
unset($arrConfig['host']);
|
|
||||||
unset($arrConfig['port']);
|
|
||||||
unset($arrConfig['mode']);
|
|
||||||
unset($arrConfig['sockType']);
|
|
||||||
unset($arrConfig['server_type']);
|
|
||||||
return $arrConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function serTcpConfig()
|
|
||||||
{
|
|
||||||
$this->Server->set($this->filterConfig());
|
|
||||||
$this->Server->on('receive', [Rout::class, 'tcpDispense']);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function createServer()
|
|
||||||
{
|
|
||||||
switch ($this->arrConfig['server_type']) {
|
|
||||||
case 'HTTP':
|
|
||||||
$this->Server = new \Swoole\Http\Server($this->arrConfig['host'], $this->arrConfig['port']);
|
|
||||||
$this->serHttpConfig();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->Server = new \Swoole\Server($this->arrConfig['host'], $this->arrConfig['port'], $this->arrConfig['mode'], $this->arrConfig['sockType']);
|
|
||||||
$this->serTcpConfig();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Server->on('task', [$this, 'onTask']);
|
|
||||||
|
|
||||||
$this->Server->on('finish', [$this, 'onFinish']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getServer()
|
|
||||||
{
|
|
||||||
return $this->Server;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onTask($Http, $task_id, $from_id, $arrData)
|
|
||||||
{
|
|
||||||
$mixedResult = call_user_func_array($arrData[0], $arrData[1]);
|
|
||||||
|
|
||||||
$Http->finish($mixedResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onFinish($Http, $task_id, $mixedData) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ServerManage
|
|
||||||
{
|
|
||||||
static $HttpService;
|
|
||||||
|
|
||||||
static $arrDynamicConfig = [];
|
|
||||||
|
|
||||||
public function __init($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->setConfigDaemonize($arrArgvs[0]['daemonize'] ?? 'false');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setConfigDaemonize($strMode)
|
|
||||||
{
|
|
||||||
self::$arrDynamicConfig['daemonize'] = (bool)$strMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getPid()
|
|
||||||
{
|
|
||||||
return file_exists(config('task.service.pid_file')) ? file_get_contents(config('task.service.pid_file')) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function start($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->__init($arrArgvs);
|
|
||||||
|
|
||||||
$intPid = (int)$this->getPid();
|
|
||||||
|
|
||||||
if ($intPid > 0 && \Swoole\Process::kill($intPid, SIG_DFL)) {
|
|
||||||
echo " Service is \e[0;32mRunning\e[0m ! " . PHP_EOL;
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
echo " Execute the \e[0;32m start\e[0m command ...... " . PHP_EOL;
|
|
||||||
|
|
||||||
$this->createService();
|
|
||||||
|
|
||||||
$this->addProcessList();
|
|
||||||
|
|
||||||
$this->addScheduledTasks();
|
|
||||||
|
|
||||||
self::$HttpService->getServer()->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stop($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->__init($arrArgvs);
|
|
||||||
|
|
||||||
$intPid = (int)$this->getPid();
|
|
||||||
|
|
||||||
if ($intPid <= 0) {
|
|
||||||
echo " Service is \e[0;31mStop\e[0m ! " . PHP_EOL;
|
|
||||||
} else {
|
|
||||||
echo " Execute the \e[0;32m stop\e[0m command ...... " . PHP_EOL;
|
|
||||||
\Swoole\Process::kill($intPid, SIGTERM);
|
|
||||||
echo " Service is \e[0;31mStop\e[0m ! " . PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function status($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->__init($arrArgvs);
|
|
||||||
|
|
||||||
$intPid = (int)$this->getPid();
|
|
||||||
|
|
||||||
if ($intPid <= 0) {
|
|
||||||
echo " Service is \e[0;31mStop\e[0m ! " . PHP_EOL;
|
|
||||||
} else if (\Swoole\Process::kill($intPid, SIG_DFL)) {
|
|
||||||
echo " Service is \e[0;32mRunning\e[0m ! " . PHP_EOL;
|
|
||||||
} else {
|
|
||||||
echo " Service is \e[0;31mStop\e[0m ! " . PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function restart($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->__init($arrArgvs);
|
|
||||||
|
|
||||||
$intPid = (int)$this->getPid();
|
|
||||||
|
|
||||||
if ($intPid <= 0) {
|
|
||||||
echo " \e[0;31m Get Pid Error\e[0m !" . PHP_EOL;
|
|
||||||
echo " Execute the \e[0;32m start\e[0m command ...... " . PHP_EOL;
|
|
||||||
$this->start();
|
|
||||||
} else {
|
|
||||||
echo " Execute the \e[0;32m restart\e[0m command ...... " . PHP_EOL;
|
|
||||||
\Swoole\Process::kill($intPid, SIGUSR1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addScheduledTasks()
|
|
||||||
{
|
|
||||||
if (config('task.scheduled_tasks_pool')) {
|
|
||||||
foreach (config('task.scheduled_tasks_pool') as $arrProcessTask) {
|
|
||||||
if ($arrProcessTask['status']) {
|
|
||||||
$Process = new \Swoole\Process(function () use ($arrProcessTask) {
|
|
||||||
call_user_func([ScheduledTasks::class, 'hander'], $arrProcessTask);
|
|
||||||
});
|
|
||||||
self::$HttpService->getServer()->addProcess($Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addProcessList()
|
|
||||||
{
|
|
||||||
if (config('task.process_pool')) {
|
|
||||||
foreach (config('task.process_pool') as $v) {
|
|
||||||
for ($i = 0; $i < $v['Num']; $i++) {
|
|
||||||
$Process = new \Swoole\Process($v['callback']);
|
|
||||||
|
|
||||||
self::$HttpService->getServer()->addProcess($Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function createService()
|
|
||||||
{
|
|
||||||
$arrHttpServiceConfig = array_merge(config('task.service'), self::$arrDynamicConfig);
|
|
||||||
|
|
||||||
self::$HttpService = ServerCore::instance($arrHttpServiceConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
declare (strict_types = 1);
|
|
||||||
|
|
||||||
namespace minserver;
|
|
||||||
|
|
||||||
use think\Container;
|
|
||||||
use think\facade\Db;
|
|
||||||
|
|
||||||
class ProcessSanitizer
|
|
||||||
{
|
|
||||||
static public function reloadRedis()
|
|
||||||
{
|
|
||||||
Container::getInstance()->delete('cache');
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function reloadDb()
|
|
||||||
{
|
|
||||||
Db::close();
|
|
||||||
Container::getInstance()->delete('think\DbManager');
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function destructConnectSource()
|
|
||||||
{
|
|
||||||
self::reloadDb();
|
|
||||||
self::reloadRedis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace minserver;
|
|
||||||
|
|
||||||
use think\facade\Cache;
|
|
||||||
|
|
||||||
class QueueManage
|
|
||||||
{
|
|
||||||
public $strQueueName = '';
|
|
||||||
|
|
||||||
static private $arrObj = [];
|
|
||||||
|
|
||||||
static public function getInstance($intIndex = 1, $strQueueName = '')
|
|
||||||
{
|
|
||||||
$strKey = $intIndex . '-' . $strQueueName;
|
|
||||||
|
|
||||||
if (!key_exists($strKey, self::$arrObj)) {
|
|
||||||
self::$arrObj[$strKey] = new self($intIndex, $strQueueName);
|
|
||||||
}
|
|
||||||
return self::$arrObj[$strKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct($intIndex = 1, $strQueueName = '')
|
|
||||||
{
|
|
||||||
if ($strQueueName == '') {
|
|
||||||
$arrConfig = config('task.queue');
|
|
||||||
$strQueueName = $arrConfig[$intIndex]['name'];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->strQueueName = $strQueueName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function get()
|
|
||||||
{
|
|
||||||
return Cache::store('redis')->lpop($this->strQueueName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function set($arrData)
|
|
||||||
{
|
|
||||||
$strData = json_encode($arrData);
|
|
||||||
return Cache::store('redis')->rpush($this->strQueueName, $strData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace minserver;
|
|
||||||
|
|
||||||
class Rout
|
|
||||||
{
|
|
||||||
static public function httpDispense(\Swoole\Http\Request $Request, \Swoole\Http\Response $Response)
|
|
||||||
{
|
|
||||||
$Response->status(999, 'Hei Guys ~');
|
|
||||||
$Response->header("Content-Type", "text/html; charset=utf-8");
|
|
||||||
$Response->end("<h1>Hello reptile~. #" . rand(1000, 9999) . "</h1>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static public function tcpDispense(\Swoole\Server $server, $fd, $reactor_id, $mixedData) {}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace minserver;
|
|
||||||
|
|
||||||
use minserver\ProcessSanitizer;
|
|
||||||
|
|
||||||
class ScheduledTasks
|
|
||||||
{
|
|
||||||
static public function hander($arrProcessTask = [])
|
|
||||||
{
|
|
||||||
ProcessSanitizer::destructConnectSource();
|
|
||||||
|
|
||||||
call_user_func($arrProcessTask['callback'], $arrProcessTask['param']);
|
|
||||||
|
|
||||||
sleep($arrProcessTask['execution_interval']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace minserver;
|
|
||||||
|
|
||||||
use think\console\Command;
|
|
||||||
use think\console\Input;
|
|
||||||
use think\console\input\Argument;
|
|
||||||
use think\console\Output;
|
|
||||||
use think\console\input\Option;
|
|
||||||
|
|
||||||
class ServerConsole extends Command
|
|
||||||
{
|
|
||||||
private $arrArguments = [
|
|
||||||
'action' => ['start', 'stop', 'restart', 'status',],
|
|
||||||
'daemonize' => ['d', "false",],
|
|
||||||
'forcibly' => ['f', "false",],
|
|
||||||
];
|
|
||||||
|
|
||||||
private $arrReflection = [
|
|
||||||
\minserver\ServerManage::class,
|
|
||||||
];
|
|
||||||
|
|
||||||
protected function configure()
|
|
||||||
{
|
|
||||||
$this->setName('php think task')
|
|
||||||
->addArgument('action', Argument::REQUIRED, "action: (" . implode('|', $this->arrArguments['action']) . ')')
|
|
||||||
->addOption('daemonize', 'd', Option::VALUE_NONE, "daemonize start service")
|
|
||||||
->addOption('forcibly', 'f', Option::VALUE_NONE, "ignore user forcibly start service")
|
|
||||||
->setDescription('swoole task server')
|
|
||||||
->setHelp('php think task <action> [-d] [-f] run server');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected function checkUser(Input $Input)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!$Input->getOption('forcibly')) {
|
|
||||||
$strUser = get_current_user();
|
|
||||||
|
|
||||||
if ($strUser == 'root') {
|
|
||||||
$strError = sprintf("Sorry , Can't start service by [%s] user!,\n but you can add option '-f' forcibly start on you debug ,\n Do not use in production environment !!!!!!!!!",$strUser);
|
|
||||||
throw new \InvalidArgumentException($strError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($strUser != 'www') {
|
|
||||||
throw new \InvalidArgumentException("Sorry , Can't start service by [{$strUser}] user!, please use [www] user !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function execute(Input $Input, Output $Output)
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->checkArguments(['action'], $Input, $Output);
|
|
||||||
|
|
||||||
$strAction = trim($Input->getArgument('action'));
|
|
||||||
|
|
||||||
if ($strAction == 'start' || $strAction == 'restart') {
|
|
||||||
$this->checkUser($Input);
|
|
||||||
}
|
|
||||||
|
|
||||||
$arrArgs = array_merge($Input->getArguments(), $Input->getOptions());
|
|
||||||
|
|
||||||
$this->{$strAction}($arrArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function checkArguments($arrArguments, Input $Input)
|
|
||||||
{
|
|
||||||
foreach ($arrArguments as $strArguments) {
|
|
||||||
$strVal = trim($Input->getArgument($strArguments));
|
|
||||||
|
|
||||||
if (!in_array($strVal, $this->arrArguments[$strArguments])) {
|
|
||||||
throw new \InvalidArgumentException("Arguments [{$strVal}] is not defined! Optional parameters [" . implode(' ', $this->arrArguments[$strArguments]) . "] !");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __call($strAction, $arrArguments)
|
|
||||||
{
|
|
||||||
foreach ($this->arrReflection as $strClass) {
|
|
||||||
if (method_exists($strClass, $strAction)) {
|
|
||||||
return call_user_func([new $strClass, $strAction], $arrArguments);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new \InvalidArgumentException("Action [{$strAction}] no method available! ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace minserver;
|
|
||||||
|
|
||||||
class ServerCore
|
|
||||||
{
|
|
||||||
private $arrConfig;
|
|
||||||
|
|
||||||
private static $obj;
|
|
||||||
|
|
||||||
private $Server;
|
|
||||||
|
|
||||||
static $Process = NULL;
|
|
||||||
|
|
||||||
static function instance($arrConfig)
|
|
||||||
{
|
|
||||||
if (self::$obj == null) {
|
|
||||||
self::$obj = new self($arrConfig);
|
|
||||||
}
|
|
||||||
return self::$obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function __construct($arrConfig)
|
|
||||||
{
|
|
||||||
$this->arrConfig = $arrConfig;
|
|
||||||
$this->createServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function serHttpConfig()
|
|
||||||
{
|
|
||||||
$this->Server->set($this->filterConfig());
|
|
||||||
$this->Server->on('request', [\minserver\Rout::class, 'httpDispense']);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function filterConfig()
|
|
||||||
{
|
|
||||||
$arrConfig = $this->arrConfig;
|
|
||||||
unset($arrConfig['host']);
|
|
||||||
unset($arrConfig['port']);
|
|
||||||
unset($arrConfig['mode']);
|
|
||||||
unset($arrConfig['sockType']);
|
|
||||||
unset($arrConfig['server_type']);
|
|
||||||
return $arrConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function serTcpConfig()
|
|
||||||
{
|
|
||||||
$this->Server->set($this->filterConfig());
|
|
||||||
$this->Server->on('receive', [\minserver\Rout::class, 'tcpDispense']);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function createServer()
|
|
||||||
{
|
|
||||||
switch ($this->arrConfig['server_type']) {
|
|
||||||
case 'HTTP':
|
|
||||||
$this->Server = new \Swoole\Http\Server($this->arrConfig['host'], $this->arrConfig['port']);
|
|
||||||
$this->serHttpConfig();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->Server = new \Swoole\Server($this->arrConfig['host'], $this->arrConfig['port'], $this->arrConfig['mode'], $this->arrConfig['sockType']);
|
|
||||||
$this->serTcpConfig();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->Server->on('task', [$this, 'onTask']);
|
|
||||||
|
|
||||||
$this->Server->on('finish', [$this, 'onFinish']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getServer()
|
|
||||||
{
|
|
||||||
return $this->Server;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onTask($Http, $task_id, $from_id, $arrData)
|
|
||||||
{
|
|
||||||
$mixedResult = call_user_func_array($arrData[0], $arrData[1]);
|
|
||||||
|
|
||||||
$Http->finish($mixedResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function onFinish($Http, $task_id, $mixedData)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace minserver;
|
|
||||||
|
|
||||||
class ServerManage
|
|
||||||
{
|
|
||||||
static $HttpService;
|
|
||||||
|
|
||||||
static $arrDynamicConfig = [];
|
|
||||||
|
|
||||||
public function __init($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->setConfigDaemonize($arrArgvs[0]['daemonize'] ?? 'false');
|
|
||||||
}
|
|
||||||
|
|
||||||
private function setConfigDaemonize($strMode)
|
|
||||||
{
|
|
||||||
self::$arrDynamicConfig['daemonize'] = (bool)$strMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getPid()
|
|
||||||
{
|
|
||||||
return file_exists(config('task.service.pid_file')) ? file_get_contents(config('task.service.pid_file')) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function start($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->__init($arrArgvs);
|
|
||||||
|
|
||||||
$intPid = (int)$this->getPid();
|
|
||||||
|
|
||||||
if ($intPid > 0 && \Swoole\Process::kill($intPid, SIG_DFL)) {
|
|
||||||
echo " Service is \e[0;32mRunning\e[0m ! " . PHP_EOL;
|
|
||||||
exit;
|
|
||||||
}
|
|
||||||
echo " Execute the \e[0;32m start\e[0m command ...... " . PHP_EOL;
|
|
||||||
|
|
||||||
$this->createService();
|
|
||||||
|
|
||||||
$this->addProcessList();
|
|
||||||
|
|
||||||
$this->addScheduledTasks();
|
|
||||||
|
|
||||||
self::$HttpService->getServer()->start();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stop($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->__init($arrArgvs);
|
|
||||||
|
|
||||||
$intPid = (int)$this->getPid();
|
|
||||||
|
|
||||||
if ($intPid <= 0) {
|
|
||||||
echo " Service is \e[0;31mStop\e[0m ! " . PHP_EOL;
|
|
||||||
} else {
|
|
||||||
echo " Execute the \e[0;32m stop\e[0m command ...... " . PHP_EOL;
|
|
||||||
\Swoole\Process::kill($intPid, SIGTERM);
|
|
||||||
echo " Service is \e[0;31mStop\e[0m ! " . PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function status($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->__init($arrArgvs);
|
|
||||||
|
|
||||||
$intPid = (int)$this->getPid();
|
|
||||||
|
|
||||||
if ($intPid <= 0) {
|
|
||||||
echo " Service is \e[0;31mStop\e[0m ! " . PHP_EOL;
|
|
||||||
} else if (\Swoole\Process::kill($intPid, SIG_DFL)) {
|
|
||||||
echo " Service is \e[0;32mRunning\e[0m ! " . PHP_EOL;
|
|
||||||
} else {
|
|
||||||
echo " Service is \e[0;31mStop\e[0m ! " . PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function restart($arrArgvs = [])
|
|
||||||
{
|
|
||||||
$this->__init($arrArgvs);
|
|
||||||
|
|
||||||
$intPid = (int)$this->getPid();
|
|
||||||
|
|
||||||
if ($intPid <= 0) {
|
|
||||||
echo " \e[0;31m Get Pid Error\e[0m !" . PHP_EOL;
|
|
||||||
echo " Execute the \e[0;32m start\e[0m command ...... " . PHP_EOL;
|
|
||||||
$this->start();
|
|
||||||
} else {
|
|
||||||
echo " Execute the \e[0;32m restart\e[0m command ...... " . PHP_EOL;
|
|
||||||
\Swoole\Process::kill($intPid, SIGUSR1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addScheduledTasks()
|
|
||||||
{
|
|
||||||
if (config('task.scheduled_tasks_pool')) {
|
|
||||||
foreach (config('task.scheduled_tasks_pool') as $arrProcessTask) {
|
|
||||||
if ($arrProcessTask['status']) {
|
|
||||||
$Process = new \Swoole\Process(function () use ($arrProcessTask) {
|
|
||||||
call_user_func([\minserver\ScheduledTasks::class, 'hander'], $arrProcessTask);
|
|
||||||
});
|
|
||||||
self::$HttpService->getServer()->addProcess($Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addProcessList()
|
|
||||||
{
|
|
||||||
if (config('task.process_pool')) {
|
|
||||||
foreach (config('task.process_pool') as $v) {
|
|
||||||
for ($i = 0; $i < $v['Num']; $i++) {
|
|
||||||
$Process = new \Swoole\Process($v['callback']);
|
|
||||||
|
|
||||||
self::$HttpService->getServer()->addProcess($Process);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function createService()
|
|
||||||
{
|
|
||||||
$arrHttpServiceConfig = array_merge(config('task.service'), self::$arrDynamicConfig);
|
|
||||||
|
|
||||||
self::$HttpService = ServerCore::instance($arrHttpServiceConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user