摘要:以上是服務(wù)啟動過程中的主體設(shè)計,其中包括了各種組件的實(shí)例化,如對象池等。
EasySwoole 服務(wù)啟動過程以及主體設(shè)計流程源碼解析
本文主要講解EasySwoole 服務(wù)的啟動過程,會通過源碼片段講解主體的設(shè)計流程
命令啟動當(dāng)我們通過php easyswoole start啟動EasySwoole 服務(wù)時,命令真正到達(dá)的文件是 easyswoole項(xiàng)目vendoreasyswooleeasyswooleineasyswoole,命令start執(zhí)行的整體流程如下圖:
主要方法為:serverStart($options);,其重要執(zhí)行代碼如下:
$conf = Conf::getInstance(); $inst = Core::getInstance()->initialize(); $inst->run();
初始化Conf,即Config對象(Config類為一個單例對象),加載全局配置信息,默認(rèn)配置Config.php內(nèi)容如下:
return [ "SERVER_NAME"=>"EasySwoole", "MAIN_SERVER"=>[ "HOST"=>"0.0.0.0", "PORT"=>9501, "SERVER_TYPE"=>EasySwooleCoreSwooleServerManager::TYPE_WEB_SERVER, "SOCK_TYPE"=>SWOOLE_TCP,//該配置項(xiàng)當(dāng)為SERVER_TYPE值為TYPE_SERVER時有效 "RUN_MODEL"=>SWOOLE_PROCESS, "SETTING"=>[ "task_worker_num" => 8, //異步任務(wù)進(jìn)程 "task_max_request"=>10, "max_request"=>5000,//強(qiáng)烈建議設(shè)置此配置項(xiàng) "worker_num"=>8 ], ], "DEBUG"=>true, "TEMP_DIR"=>null,//若不配置,則默認(rèn)框架初始化 "LOG_DIR"=>null,//若不配置,則默認(rèn)框架初始化 "EASY_CACHE"=>[ "PROCESS_NUM"=>1,//若不希望開啟,則設(shè)置為0 "PERSISTENT_TIME"=>0//如果需要定時數(shù)據(jù)落地,請設(shè)置對應(yīng)的時間周期,單位為秒 ], "CLUSTER"=>[ "enable"=>false, "token"=>null, "broadcastAddress"=>["255.255.255.255:9556"], "listenAddress"=>"0.0.0.0", "listenPort"=>"9556", "broadcastTTL"=>5, "nodeTimeout"=>10, "nodeName"=>"easySwoole", "nodeId"=>null ] ];
執(zhí)行入口文件Code.php對象的initialize()方法
執(zhí)行入口文件Code.php對象的run()方法
ps:此處插入說明一個點(diǎn),EasySwoole中單例類都復(fù)用同一個trait
trait Singleton { private static $instance; static function getInstance(...$args) { if(!isset(self::$instance)){ self::$instance = new static(...$args); } return self::$instance; } }入口文件
Easywechat 真實(shí)入口文件為EasySwooleCoreCore,上述已經(jīng)說到命令啟動時,執(zhí)行了以下代碼:
Core::getInstance(); $inst = Core::getInstance()->initialize(); $inst->run();
在整個EasySwoole生命周期中,Core對象只會被實(shí)例化一次,Code的初始化做了如下操作:
public function __construct() { defined("SWOOLE_VERSION") or define("SWOOLE_VERSION",intval(phpversion("swoole"))); defined("EASYSWOOLE_ROOT") or define("EASYSWOOLE_ROOT",realpath(getcwd())); if(file_exists(EASYSWOOLE_ROOT."/EasySwooleEvent.php")){ require_once EASYSWOOLE_ROOT."/EasySwooleEvent.php"; //引入全局初始化事件類 } $this->sysDirectoryInit(); //設(shè)置temp目錄和log目錄,路徑可配置化 }
定義了全局宏SWOOLE_VERSION 和 EASYSWOOLE_ROOT
引入了全局初始化事件類EasySwooleEvent.php
$this->sysDirectoryInit(); 設(shè)置temp目錄和log目錄,路徑可配置化
Core類中的initialize方法:
public function initialize():Core { Di::getInstance()->set(SysConst::VERSION,"2.1.2"); Di::getInstance()->set(SysConst::HTTP_CONTROLLER_MAX_DEPTH,3); EasySwooleEvent::frameInitialize(); $this->errorHandle(); return $this; }
DI容器注入SysConst::VERSION 和 SysConst::HTTP_CONTROLLER_MAX_DEPTH 的值
執(zhí)行全局事件類EasySwooleEvent::frameInitialize();事件
$this->errorHandle();注冊系統(tǒng)中的set_error_handler、register_shutdown_function
Core類的run方法為核心功能:
public function run():void { ServerManager::getInstance()->start(); }
實(shí)例化ServerManager類,并執(zhí)行start() 啟動整個服務(wù)
服務(wù)管理類 ServerManagerServerManager是一個單例對象,在整個EasySwoole生命周期中,ServeManager對象只會被實(shí)例化一次.
ServeManager 的 run 方法干了下面幾件事:
public function start():void { $this->createMainServer(); Cache::getInstance(); Cluster::getInstance()->run(); CronTab::getInstance()->run(); $this->attachListener(); $this->isStart = true; $this->getServer()->start(); }
createMainServer() 創(chuàng)建主服務(wù)
初始化緩存服務(wù) cache,添加對應(yīng)的CacheProcess。(Easyswoole的緩存服務(wù)是基于swoole_process的管道通信,后續(xù)會專門解析下系統(tǒng)組件cache的源碼)
Cluster集群模式的注冊 (有興趣的可以通過鏈接看看)
CronTab 服務(wù)開啟,后面說下crontab的使用
attachListener事件監(jiān)聽,子服務(wù)多端口監(jiān)聽
$this->getServer()->start(); 調(diào)用swoole_server的start方法,正式啟動Easyswoole服務(wù)
ServerManager 類的createMainServer()方法:
(1)讀取配置,創(chuàng)建對應(yīng)的swoole_server服務(wù)
case self::TYPE_SERVER:{ $this->mainServer = new swoole_server($host,$port,$runModel,$sockType); break; } case self::TYPE_WEB_SERVER:{ $this->mainServer = new swoole_http_server($host,$port,$runModel,$sockType); break; } case self::TYPE_WEB_SOCKET_SERVER:{ $this->mainServer = new swoole_websocket_server($host,$port,$runModel,$sockType); break; } default:{ Trigger::throwable(new Exception("unknown server type :{$conf["SERVER_TYPE"]}")); } }
(2)注冊事件,onWorker、onTask、onFinish、onRequest等;還有easySwoole事件mainServerCreate,開發(fā)者可以在mainServerCreate事件設(shè)置Crontab 服務(wù)等
$register = new EventRegister();//事件容器 $this->finalHook($register); EasySwooleEvent::mainServerCreate($this,$register); $events = $register->all();
(3)事件注冊的過程中,還做了如下操作:實(shí)例化對象池。開發(fā)者可以通過配置,在此實(shí)例化mysql連接池等:
//實(shí)例化對象池管理 PoolManager::getInstance(); PoolManager::getInstance()->__workerStartHook($workerId);
(4)在onRequest事件中,還執(zhí)行了EasySwooleEvent的onRequest和afterAction,開發(fā)者可以在此自定義處理代碼,如日志統(tǒng)一刷出等
EasySwooleEvent::onRequest($request_psr,$response_psr); $dispatcher->dispatch($request_psr,$response_psr); EasySwooleEvent::afterAction($request_psr,$response_psr);
ServerManager 中 Cache::getInstance() 全局跨進(jìn)程Cache的注冊:
function __construct() { $num = intval(Config::getInstance()->getConf("EASY_CACHE.PROCESS_NUM")); if($num <= 0){ return; } $this->cliTemp = new SplArray(); //若是在主服務(wù)創(chuàng)建,而非單元測試調(diào)用 if(ServerManager::getInstance()->getServer()){ //創(chuàng)建table用于數(shù)據(jù)傳遞 TableManager::getInstance()->add(self::EXCHANGE_TABLE_NAME,[ "data"=>[ "type"=>Table::TYPE_STRING, "size"=>10*1024 ], "microTime"=>[ "type"=>Table::TYPE_STRING, "size"=>15 ] ],2048); $this->processNum = $num; for ($i=0;$i < $num;$i++){ ProcessManager::getInstance()->addProcess($this->generateProcessName($i),CacheProcess::class); } } }
Cache 服務(wù)基于 swoole_table 實(shí)現(xiàn)全局?jǐn)?shù)據(jù)共享和傳遞。
以上是EasySwoole服務(wù)啟動過程中的主體設(shè)計,其中包括了各種組件的實(shí)例化,如PoolManager(對象池)、cache、CronTab等。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/28777.html
摘要:易用穩(wěn)定,本次想通過對的學(xué)習(xí)和個人解析,吸收框架的思想和設(shè)計知識,加強(qiáng)自己對的認(rèn)知和理解。當(dāng)然,筆者能力水平有限,后續(xù)的文章如有錯誤,還請指出和諒解。目錄如下后續(xù)添加文章都會記錄在此服務(wù)啟動過程以及主體設(shè)計流程源碼解析 前言 swoole是什么?官網(wǎng)的原話介紹是這樣的: Swoole 使用純 C 語言編寫,提供了 PHP 語言的異步多線程服務(wù)器,異步 TCP/UDP 網(wǎng)絡(luò)客戶端,異步 ...
摘要:組件提供了很多實(shí)用的組件包括控制臺組件定時器觸發(fā)器日志處理等等致謝從下一章開始,我們逐步使用的各項(xiàng)功能并開發(fā)一個簡單的并發(fā)版爬蟲系統(tǒng),感謝你看到這里,希望本文可以幫到你,謝謝 showImg(https://segmentfault.com/img/bVbpts4?w=640&h=160); 前言 我一生的文章都會放在這里,我的博客,我希望每一行代碼,每一段文字都能幫助你。https:...
摘要:然而盡管如此,很多人可能都沒有思考過,如何優(yōu)雅的寫出自己的物聯(lián)網(wǎng)服務(wù)器。 PHP不適合做物聯(lián)網(wǎng)服務(wù)端嗎? 在傳統(tǒng)的思維中,經(jīng)常會有人告訴你,php不適合用來做物聯(lián)網(wǎng)服務(wù)端,讓你換java,node,go等其他語言,是的,沒錯傳統(tǒng)意義上的php,確實(shí)很難做物聯(lián)網(wǎng)服務(wù)器,因?yàn)樗鼘?shí)在太蹩腳了,當(dāng)然,這也不是意味著徹底就不能做。舉個例子,當(dāng)你想實(shí)現(xiàn)一個TCP服務(wù)器的時候,你可能需要寫出原理大約...
摘要:暑假的時候在學(xué)習(xí)了并成功運(yùn)用到了項(xiàng)目中。這是提供的一個安全權(quán)限控制框架,可以根據(jù)使用者的需要定制相關(guān)的角色身份和身份所具有的權(quán)限,完成黑名單操作攔截?zé)o權(quán)限的操作。用戶通過登陸操作獲得我們返回的并保存在本地。 暑假的時候在學(xué)習(xí)了 Spring Security 并成功運(yùn)用到了項(xiàng)目中。 在實(shí)踐中摸索出了一套結(jié)合 json + jwt(json web token) + Spring Boo...
閱讀 2634·2021-09-30 10:00
閱讀 3556·2021-09-22 10:54
閱讀 6622·2021-09-07 10:28
閱讀 3056·2019-08-29 13:53
閱讀 801·2019-08-29 12:42
閱讀 1033·2019-08-26 13:51
閱讀 1323·2019-08-26 13:32
閱讀 3084·2019-08-26 10:39