摘要:以上是服務啟動過程中的主體設計,其中包括了各種組件的實例化,如對象池等。
EasySwoole 服務啟動過程以及主體設計流程源碼解析
本文主要講解EasySwoole 服務的啟動過程,會通過源碼片段講解主體的設計流程
命令啟動當我們通過php easyswoole start啟動EasySwoole 服務時,命令真正到達的文件是 easyswoole項目vendoreasyswooleeasyswooleineasyswoole,命令start執行的整體流程如下圖:
主要方法為:serverStart($options);,其重要執行代碼如下:
$conf = Conf::getInstance(); $inst = Core::getInstance()->initialize(); $inst->run();
初始化Conf,即Config對象(Config類為一個單例對象),加載全局配置信息,默認配置Config.php內容如下:
return [ "SERVER_NAME"=>"EasySwoole", "MAIN_SERVER"=>[ "HOST"=>"0.0.0.0", "PORT"=>9501, "SERVER_TYPE"=>EasySwooleCoreSwooleServerManager::TYPE_WEB_SERVER, "SOCK_TYPE"=>SWOOLE_TCP,//該配置項當為SERVER_TYPE值為TYPE_SERVER時有效 "RUN_MODEL"=>SWOOLE_PROCESS, "SETTING"=>[ "task_worker_num" => 8, //異步任務進程 "task_max_request"=>10, "max_request"=>5000,//強烈建議設置此配置項 "worker_num"=>8 ], ], "DEBUG"=>true, "TEMP_DIR"=>null,//若不配置,則默認框架初始化 "LOG_DIR"=>null,//若不配置,則默認框架初始化 "EASY_CACHE"=>[ "PROCESS_NUM"=>1,//若不希望開啟,則設置為0 "PERSISTENT_TIME"=>0//如果需要定時數據落地,請設置對應的時間周期,單位為秒 ], "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 ] ];
執行入口文件Code.php對象的initialize()方法
執行入口文件Code.php對象的run()方法
ps:此處插入說明一個點,EasySwoole中單例類都復用同一個trait
trait Singleton { private static $instance; static function getInstance(...$args) { if(!isset(self::$instance)){ self::$instance = new static(...$args); } return self::$instance; } }入口文件
Easywechat 真實入口文件為EasySwooleCoreCore,上述已經說到命令啟動時,執行了以下代碼:
Core::getInstance(); $inst = Core::getInstance()->initialize(); $inst->run();
在整個EasySwoole生命周期中,Core對象只會被實例化一次,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(); //設置temp目錄和log目錄,路徑可配置化 }
定義了全局宏SWOOLE_VERSION 和 EASYSWOOLE_ROOT
引入了全局初始化事件類EasySwooleEvent.php
$this->sysDirectoryInit(); 設置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 的值
執行全局事件類EasySwooleEvent::frameInitialize();事件
$this->errorHandle();注冊系統中的set_error_handler、register_shutdown_function
Core類的run方法為核心功能:
public function run():void { ServerManager::getInstance()->start(); }
實例化ServerManager類,并執行start() 啟動整個服務
服務管理類 ServerManagerServerManager是一個單例對象,在整個EasySwoole生命周期中,ServeManager對象只會被實例化一次.
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() 創建主服務
初始化緩存服務 cache,添加對應的CacheProcess。(Easyswoole的緩存服務是基于swoole_process的管道通信,后續會專門解析下系統組件cache的源碼)
Cluster集群模式的注冊 (有興趣的可以通過鏈接看看)
CronTab 服務開啟,后面說下crontab的使用
attachListener事件監聽,子服務多端口監聽
$this->getServer()->start(); 調用swoole_server的start方法,正式啟動Easyswoole服務
ServerManager 類的createMainServer()方法:
(1)讀取配置,創建對應的swoole_server服務
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,開發者可以在mainServerCreate事件設置Crontab 服務等
$register = new EventRegister();//事件容器 $this->finalHook($register); EasySwooleEvent::mainServerCreate($this,$register); $events = $register->all();
(3)事件注冊的過程中,還做了如下操作:實例化對象池。開發者可以通過配置,在此實例化mysql連接池等:
//實例化對象池管理 PoolManager::getInstance(); PoolManager::getInstance()->__workerStartHook($workerId);
(4)在onRequest事件中,還執行了EasySwooleEvent的onRequest和afterAction,開發者可以在此自定義處理代碼,如日志統一刷出等
EasySwooleEvent::onRequest($request_psr,$response_psr); $dispatcher->dispatch($request_psr,$response_psr); EasySwooleEvent::afterAction($request_psr,$response_psr);
ServerManager 中 Cache::getInstance() 全局跨進程Cache的注冊:
function __construct() { $num = intval(Config::getInstance()->getConf("EASY_CACHE.PROCESS_NUM")); if($num <= 0){ return; } $this->cliTemp = new SplArray(); //若是在主服務創建,而非單元測試調用 if(ServerManager::getInstance()->getServer()){ //創建table用于數據傳遞 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 服務基于 swoole_table 實現全局數據共享和傳遞。
以上是EasySwoole服務啟動過程中的主體設計,其中包括了各種組件的實例化,如PoolManager(對象池)、cache、CronTab等。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/28777.html
摘要:易用穩定,本次想通過對的學習和個人解析,吸收框架的思想和設計知識,加強自己對的認知和理解。當然,筆者能力水平有限,后續的文章如有錯誤,還請指出和諒解。目錄如下后續添加文章都會記錄在此服務啟動過程以及主體設計流程源碼解析 前言 swoole是什么?官網的原話介紹是這樣的: Swoole 使用純 C 語言編寫,提供了 PHP 語言的異步多線程服務器,異步 TCP/UDP 網絡客戶端,異步 ...
摘要:組件提供了很多實用的組件包括控制臺組件定時器觸發器日志處理等等致謝從下一章開始,我們逐步使用的各項功能并開發一個簡單的并發版爬蟲系統,感謝你看到這里,希望本文可以幫到你,謝謝 showImg(https://segmentfault.com/img/bVbpts4?w=640&h=160); 前言 我一生的文章都會放在這里,我的博客,我希望每一行代碼,每一段文字都能幫助你。https:...
摘要:然而盡管如此,很多人可能都沒有思考過,如何優雅的寫出自己的物聯網服務器。 PHP不適合做物聯網服務端嗎? 在傳統的思維中,經常會有人告訴你,php不適合用來做物聯網服務端,讓你換java,node,go等其他語言,是的,沒錯傳統意義上的php,確實很難做物聯網服務器,因為它實在太蹩腳了,當然,這也不是意味著徹底就不能做。舉個例子,當你想實現一個TCP服務器的時候,你可能需要寫出原理大約...
摘要:暑假的時候在學習了并成功運用到了項目中。這是提供的一個安全權限控制框架,可以根據使用者的需要定制相關的角色身份和身份所具有的權限,完成黑名單操作攔截無權限的操作。用戶通過登陸操作獲得我們返回的并保存在本地。 暑假的時候在學習了 Spring Security 并成功運用到了項目中。 在實踐中摸索出了一套結合 json + jwt(json web token) + Spring Boo...
閱讀 2567·2021-09-30 10:00
閱讀 3500·2021-09-22 10:54
閱讀 6257·2021-09-07 10:28
閱讀 2955·2019-08-29 13:53
閱讀 752·2019-08-29 12:42
閱讀 967·2019-08-26 13:51
閱讀 1264·2019-08-26 13:32
閱讀 3028·2019-08-26 10:39