摘要:以上是服務(wù)啟動(dòng)過(guò)程中的主體設(shè)計(jì),其中包括了各種組件的實(shí)例化,如對(duì)象池等。
EasySwoole 服務(wù)啟動(dòng)過(guò)程以及主體設(shè)計(jì)流程源碼解析
本文主要講解EasySwoole 服務(wù)的啟動(dòng)過(guò)程,會(huì)通過(guò)源碼片段講解主體的設(shè)計(jì)流程
命令啟動(dòng)當(dāng)我們通過(guò)php easyswoole start啟動(dòng)EasySwoole 服務(wù)時(shí),命令真正到達(dá)的文件是 easyswoole項(xiàng)目vendoreasyswooleeasyswooleineasyswoole,命令start執(zhí)行的整體流程如下圖:
主要方法為:serverStart($options);,其重要執(zhí)行代碼如下:
$conf = Conf::getInstance(); $inst = Core::getInstance()->initialize(); $inst->run();
初始化Conf,即Config對(duì)象(Config類為一個(gè)單例對(duì)象),加載全局配置信息,默認(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時(shí)有效 "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í)數(shù)據(jù)落地,請(qǐng)?jiān)O(shè)置對(duì)應(yīng)的時(shí)間周期,單位為秒 ], "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對(duì)象的initialize()方法
執(zhí)行入口文件Code.php對(duì)象的run()方法
ps:此處插入說(shuō)明一個(gè)點(diǎn),EasySwoole中單例類都復(fù)用同一個(gè)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)說(shuō)到命令啟動(dòng)時(shí),執(zhí)行了以下代碼:
Core::getInstance(); $inst = Core::getInstance()->initialize(); $inst->run();
在整個(gè)EasySwoole生命周期中,Core對(duì)象只會(huì)被實(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();注冊(cè)系統(tǒng)中的set_error_handler、register_shutdown_function
Core類的run方法為核心功能:
public function run():void { ServerManager::getInstance()->start(); }
實(shí)例化ServerManager類,并執(zhí)行start() 啟動(dòng)整個(gè)服務(wù)
服務(wù)管理類 ServerManagerServerManager是一個(gè)單例對(duì)象,在整個(gè)EasySwoole生命周期中,ServeManager對(duì)象只會(huì)被實(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,添加對(duì)應(yīng)的CacheProcess。(Easyswoole的緩存服務(wù)是基于swoole_process的管道通信,后續(xù)會(huì)專門解析下系統(tǒng)組件cache的源碼)
Cluster集群模式的注冊(cè) (有興趣的可以通過(guò)鏈接看看)
CronTab 服務(wù)開啟,后面說(shuō)下crontab的使用
attachListener事件監(jiān)聽,子服務(wù)多端口監(jiān)聽
$this->getServer()->start(); 調(diào)用swoole_server的start方法,正式啟動(dòng)Easyswoole服務(wù)
ServerManager 類的createMainServer()方法:
(1)讀取配置,創(chuàng)建對(duì)應(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)注冊(cè)事件,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)事件注冊(cè)的過(guò)程中,還做了如下操作:實(shí)例化對(duì)象池。開發(fā)者可以通過(guò)配置,在此實(shí)例化mysql連接池等:
//實(shí)例化對(duì)象池管理 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的注冊(cè):
function __construct() { $num = intval(Config::getInstance()->getConf("EASY_CACHE.PROCESS_NUM")); if($num <= 0){ return; } $this->cliTemp = new SplArray(); //若是在主服務(wù)創(chuàng)建,而非單元測(cè)試調(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ù)啟動(dòng)過(guò)程中的主體設(shè)計(jì),其中包括了各種組件的實(shí)例化,如PoolManager(對(duì)象池)、cache、CronTab等。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/28777.html
摘要:易用穩(wěn)定,本次想通過(guò)對(duì)的學(xué)習(xí)和個(gè)人解析,吸收框架的思想和設(shè)計(jì)知識(shí),加強(qiáng)自己對(duì)的認(rèn)知和理解。當(dāng)然,筆者能力水平有限,后續(xù)的文章如有錯(cuò)誤,還請(qǐng)指出和諒解。目錄如下后續(xù)添加文章都會(huì)記錄在此服務(wù)啟動(dòng)過(guò)程以及主體設(shè)計(jì)流程源碼解析 前言 swoole是什么?官網(wǎng)的原話介紹是這樣的: Swoole 使用純 C 語(yǔ)言編寫,提供了 PHP 語(yǔ)言的異步多線程服務(wù)器,異步 TCP/UDP 網(wǎng)絡(luò)客戶端,異步 ...
摘要:組件提供了很多實(shí)用的組件包括控制臺(tái)組件定時(shí)器觸發(fā)器日志處理等等致謝從下一章開始,我們逐步使用的各項(xiàng)功能并開發(fā)一個(gè)簡(jiǎn)單的并發(fā)版爬蟲系統(tǒng),感謝你看到這里,希望本文可以幫到你,謝謝 showImg(https://segmentfault.com/img/bVbpts4?w=640&h=160); 前言 我一生的文章都會(huì)放在這里,我的博客,我希望每一行代碼,每一段文字都能幫助你。https:...
摘要:然而盡管如此,很多人可能都沒(méi)有思考過(guò),如何優(yōu)雅的寫出自己的物聯(lián)網(wǎng)服務(wù)器。 PHP不適合做物聯(lián)網(wǎng)服務(wù)端嗎? 在傳統(tǒng)的思維中,經(jīng)常會(huì)有人告訴你,php不適合用來(lái)做物聯(lián)網(wǎng)服務(wù)端,讓你換java,node,go等其他語(yǔ)言,是的,沒(méi)錯(cuò)傳統(tǒng)意義上的php,確實(shí)很難做物聯(lián)網(wǎng)服務(wù)器,因?yàn)樗鼘?shí)在太蹩腳了,當(dāng)然,這也不是意味著徹底就不能做。舉個(gè)例子,當(dāng)你想實(shí)現(xiàn)一個(gè)TCP服務(wù)器的時(shí)候,你可能需要寫出原理大約...
摘要:暑假的時(shí)候在學(xué)習(xí)了并成功運(yùn)用到了項(xiàng)目中。這是提供的一個(gè)安全權(quán)限控制框架,可以根據(jù)使用者的需要定制相關(guān)的角色身份和身份所具有的權(quán)限,完成黑名單操作攔截?zé)o權(quán)限的操作。用戶通過(guò)登陸操作獲得我們返回的并保存在本地。 暑假的時(shí)候在學(xué)習(xí)了 Spring Security 并成功運(yùn)用到了項(xiàng)目中。 在實(shí)踐中摸索出了一套結(jié)合 json + jwt(json web token) + Spring Boo...
閱讀 2555·2021-09-30 10:00
閱讀 3491·2021-09-22 10:54
閱讀 6212·2021-09-07 10:28
閱讀 2943·2019-08-29 13:53
閱讀 742·2019-08-29 12:42
閱讀 958·2019-08-26 13:51
閱讀 1258·2019-08-26 13:32
閱讀 3021·2019-08-26 10:39