EasySwoole 服务启动过程以及主体设计流程源码解析

本文主要讲解EasySwoole 服务的启动过程,会通过源码片段讲解主体的设计流程

命令启动

当我们通过php easyswoole start启动EasySwoole 服务时,命令真正到达的文件是 easyswoole项目\vendor\easyswoole\easyswoole\bin\easyswoole,命令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'=>\EasySwoole\Core\Swoole\ServerManager::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 真实入口文件为EasySwoole\Core\Core,上述已经说到命令启动时,执行了以下代码:

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() 启动整个服务

服务管理类 ServerManager

ServerManager是一个单例对象,在整个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等。

swoole 启动流程_EasySwoole 服务启动过程以及主体设计流程源码解析相关推荐

  1. Android Launcher启动应用程序流程源码解析

    带着问题看源码 点击桌面Launcher图标后做了哪些工作? 应用程序什么时候被创建的? Application和MainActivity的onCreate()方法什么时候被调用的? 概述 在Andr ...

  2. NioEventLoop启动流程源码解析

    NioEventLoop的启动时机是在服务端的NioServerSocketChannel中的ServerSocketChannel初始化完成,且注册在NioEventLoop后执行的, 下一步就是去 ...

  3. SpringBoot启动全流程源码解析(超详细版)

    我们在使用SpringBoot启动项目的时候,可能只需加一个注解,然后启动main,整个项目就运行了起来,但事实真的是所见即所得吗,还是SpringBoot在背后默默做了很多?本文会通过源码解析的方式 ...

  4. SpringSecurity启动流程源码解析

    前面两期我讲了SpringSecurity认证流程和SpringSecurity鉴权流程,今天是第三期,是SpringSecurity的收尾工作,讲SpringSecurity的启动流程. 就像很多电 ...

  5. Kernel启动流程源码解析 1 head.S

    bootloader在跳转到kernel前,需要确保如下设置: MMU = off, D-cache = off, I-cache = on or off x0 = physical address ...

  6. Kernel启动流程源码解析 2 head.S

    __cpu_setup.定义kernel\arch\arm64\mm\proc.S中. #define MAIR(attr, mt)    ((attr) << ((mt) * 8)) / ...

  7. Doris FE启动流程源码详细解析

    Doris FE启动流程源码详细解析 一.简介 Apache Doris是一个现代化的MPP分析型数据库产品.仅需亚秒级响应时间即可获得查询结果,有效地支持实时数据分析.Apache Doris的分布 ...

  8. SpringBoot2 | SpringBoot启动流程源码分析(一)

    首页 博客 专栏·视频 下载 论坛 问答 代码 直播 能力认证 高校 会员中心 收藏 动态 消息 创作中心 SpringBoot2 | SpringBoot启动流程源码分析(一) 置顶 张书康 201 ...

  9. NodeManager启动流程与服务

    本文介绍了NodeManager的启动流程与服务. NodeManager主流程 在main方法中new一个 NodeManager, 然后初始化并启动. 这里主要看initAndStartNodeM ...

最新文章

  1. MPB:农科院牧医所赵圣国组-基于GraftM对功能基因进行物种注释
  2. python编写程序的一般步骤-Python编写win程序的操作流程
  3. Cloudera Enterprise 试用版 6.3.1查看cloudrea的许可证---可用期限
  4. 两个自变量和一个因变量spss_多个自变量(包括离散变量和连续变量)对一个因变量的影响(SPSS:协方差分析)...
  5. 论文浅尝 | Tree-to-sequence 学习知识问答
  6. windows+PHP+shell_exec()无法执行的原因
  7. Oracle体系结构四(学习笔记)
  8. 怎么判断我选了多少个复选框_7~8个月宝宝一天吃多少辅食,怎么安排?妈妈这样做,养出健康娃...
  9. 桌面虚拟云终端技术研究
  10. easyui---layout实战
  11. OCR文本扫描 轮廓检测 透视变换-唐宇迪笔记
  12. 【系统分析师之路】2020年下系统分析师案例分析真题
  13. html如何在表单里加虚线,大佬,表格下方的虚线怎么添加?
  14. 星星之火-50:无意中发现一种能够把网络视频下载到本地计算机中的方法
  15. 对曲面的积分求椭圆的面积_此题是关于数学考研的曲面积分题∫∫(xdydz+ydzdx+zdxdy)/(x2+y2+z2)3/2,曲面是上半椭圆球面...
  16. pdf.jsweb浏览pdf插件简单使用
  17. 出海欧洲《通用数据保护条例》解读,附GDPR白皮书下载
  18. 10分钟读懂技术分析经典—《日本蜡烛图技术》
  19. p标签和超链接的认识
  20. A095_day01_微信小程序入门与组件

热门文章

  1. MSCKF的理解(3.4之(17)-(24))以及附录
  2. 3ds Max导出带贴图的obj模型
  3. 3 GROM 关联 (golang)
  4. 从头写一个超过zip的压缩算法(8):学习tek压缩
  5. 香橙派 Orange Pi Zero2 使用配置指南
  6. The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games 阅读笔记
  7. 【深度学习与图神经网络核心技术实践应用高级研修班-Day1】深度学习的发展历史(完整版)
  8. 初刷【洛谷P2181对角线】题解心得
  9. 软件工程之软件过程结构
  10. 添加用户并配置读写权限(阁瑞钛伦特软件-九耶实训)