前文连接,阅读的时候最好参照EasySwoole2.1.2的源码

  1. $inst->run();//启动服务

这里实际调用的是Core的start方法ServerManager::getInstance()->start();

这个方法主要是启动swoole服务的

  1. //创建主服务
  2. $this->createMainServer();

在这块代码里主要是核心,是在swoole执行start服务前设置相关配置以及配置相关回调函数。具体代码如下

先给服务器配置相关运行参数

  1. $conf = Config::getInstance()->getConf("MAIN_SERVER");//获取Config.php 中配置的MAIN_SERVER数组
  2. $runModel = $conf['RUN_MODEL'];//获取运行模式 默认是SWOOLE_PROCESS模式,使用进程模式,业务代码在Worker进程中执行
  3. $host = $conf['HOST'];//获取运行的host 'HOST'=>'0.0.0.0',
  4. $port = $conf['PORT'];//获取配置的运行端口为9501 'PORT'=>9501,
  5. $setting = $conf['SETTING'];//这里设置的相关的配置项,这些配置做一些解释,参照https://wiki.swoole.com/wiki/page/274.html
  6. 'SETTING'=>[
  7. 'task_worker_num' => 8, //配置Task进程的数量,配置此参数后将会启用task功能。所以Server务必要注册onTask、onFinish2个事件回调函数。如果没有注册,服务器程序将无法启动。
  8. 'task_max_request'=>10,//设置task进程的最大任务数。一个task进程在处理完超过此数值的任务后将自动退出。这个参数是为了防止PHP进程内存溢出。如果不希望进程自动退出可以设置为0,炒鸡重要,进程中的数据,如果有一个global数组,或者全局变量,不设置这个就会不回收最终导致内存溢出
  9. 'max_request'=>5000,//设置worker进程的最大任务数,这个和task_max_request功能一样,为了解决PHP进程内存溢出问题
  10. 'worker_num'=>8//设置启动的Worker进程数
  11. ],
  12. //其实这里还有2个配置,是前文中提到的,在前文19行$this->sysDirectoryInit();会初始化配置pid_file和log_file
  13. pid_file //在Server启动时自动将master进程的PID写入到文件,在Server关闭时自动删除PID文件。
  14. log_file //指定swoole错误日志文件。在swoole运行期发生的异常信息会记录到这个文件中。默认会打印到屏幕。
  15. $sockType = $conf['SOCK_TYPE'];//指定当前运行的服务是什么服务器。有tcp服务,http服务,websocket服务。默认是tcp服务
  16. switch ($conf['SERVER_TYPE']){
  17.   case self::TYPE_SERVER:{
  18.     $this->mainServer = new \swoole_server($host,$port,$runModel,$sockType);//创建mainServer,这里创建了一个tcp服务器
  19. break;
  20. }
  21.   case self::TYPE_WEB_SERVER:{
  22.     $this->mainServer = new \swoole_http_server($host,$port,$runModel,$sockType);//web方式是默认
  23. break;
  24. }
  25.   case self::TYPE_WEB_SOCKET_SERVER:{
  26. $this->mainServer = new \swoole_websocket_server($host,$port,$runModel,$sockType);
  27. break;
  28. }
  29.   default:{
  30.     Trigger::throwable(new \Exception("unknown server type :{$conf['SERVER_TYPE']}"));
  31.   }
  32. }
  33. $this->mainServer->set($setting);//将上面的相关服务启动配置到mainServer

创建默认的事件注册器,给服务注册默认的是事件处理函数

  1. $register = new EventRegister();
  2. $this->finalHook($register);
  3. EasySwooleEvent::mainServerCreate($this,$register);//这里是框架全局事件mainServerCreate主服务创建事件
  4. $events = $register->all();
  5. //然后循环给swoole服务器绑定回调函数。这里同一个回调方法设置多个回调函数
  6. foreach ($events as $event => $callback){
  7. $this->mainServer->on($event, function () use ($callback) {
  8. $ret = [];
  9. $args = func_get_args();
  10. foreach ($callback as $item) {
  11. array_push($ret,Invoker::callUserFuncArray($item, $args));
  12. }
  13. if(count($ret) > 1){
  14. return $ret;
  15. }
  16. return array_shift($ret);
  17. });
  18. }

这里提一下finalHook具体做了什么操作

  1. $this->finalHook($register);
  1. //实例化对象池管理
  2. PoolManager::getInstance();
  3. //register,先绑定一个workerStart回调函数。此事件在Worker进程/Task进程启动时发生。这里创建的对象可以在进程全局周期内使用。
  4. $register->add($register::onWorkerStart,function (\swoole_server $server,int $workerId){
  5. PoolManager::getInstance()->__workerStartHook($workerId);
  6. $workerNum = Config::getInstance()->getConf('MAIN_SERVER.SETTING.worker_num');
  7. $name = Config::getInstance()->getConf('SERVER_NAME');
  8. if(PHP_OS != 'Darwin'){
  9. if($workerId <= ($workerNum -1)){//判断当前是否是worker进程
  10. $name = "{$name}_Worker_".$workerId;
  11. }else{//这个是task进程
  12. $name = "{$name}_Task_Worker_".$workerId;
  13. }
  14. cli_set_process_title($name);//设置当前的进程名称
  15. //图片
  16. }
  17. });
  18. //EventHelper 是一个框架提供的默认的事件处理函数(这些放到后面具体讲述)
  19. EventHelper::registerDefaultOnTask($register);//注册默认的task回调,处理task任务的具体函数
  20. EventHelper::registerDefaultOnFinish($register);//注册默认的task任务完成后的回调
  21. EventHelper::registerDefaultOnPipeMessage($register);//注册pipeMessage回调函数
  22. $conf = Config::getInstance()->getConf("MAIN_SERVER");
  23. //如果是http服务器或者websocket,需要注册request回调函数
  24. if($conf['SERVER_TYPE'] == self::TYPE_WEB_SERVER || $conf['SERVER_TYPE'] == self::TYPE_WEB_SOCKET_SERVER){
  25. if(!$register->get($register::onRequest)){
  26. EventHelper::registerDefaultOnRequest($register);//这里包含了请求,然后路由解析,处理返回的功能。就跟一般web框架类似
  27. }
  28. }  

 系统启动后,在worker启动的时候,会进行改名的操作,如下图

 

最后注册相关的cache监听端口等就启动swoole服务了。

  1. Cache::getInstance(); //这里注册Cache
  2. Cluster::getInstance()->run(); //实现RPC
  3. CronTab::getInstance()->run(); //定时任务
  4. $this->attachListener();//Swoole提供了swoole_server::addListener来增加监听的端口。业务代码中可以通过调用swoole_server::connection_info来获取某个连接来自于哪个端口。这里框架启动的时候host配置的是0.0.0.0 所以监听所有地址,就没必要设置这个了
  5. $this->isStart = true;
  6. $this->getServer()->start();//启动swoole服务器,在这之前创建的对象都在程序全局期中  

下篇文章介绍TableManager。因为它在很多地方都被用到了。  

  

二 分析easyswoole源码(启动服务)的更多相关文章

  1. 一 分析easyswoole源码(启动服务)

    分析easyswoole源码 1以启动为例 //检查是否已经安装 installCheck();//检查锁文件是否存在,不存在结束 //启动服务 serverStart showLogo();//显示 ...

  2. 四 分析easyswoole源码(启动服务&Cache组件原理)

    前文提到的在系统设置Cache组件 Cache::getInstance()的时候,会去调用processManager去创建Cache的进程,然后以管道通信的方式进行设置缓存和获取缓存. Cache ...

  3. 三 分析easyswoole源码(启动服务&TableManager,略提及Cache工具的原理)

    前文连接,讲了es是如何启动swoole服务的. 里面有一个工具类TableManager.这个类为了处理进程间数据共享.是对swoole_table的一层封装swoole_table一个基于共享内存 ...

  4. Netty源码解析---服务端启动

    Netty源码解析---服务端启动 一个简单的服务端代码: public class SimpleServer { public static void main(String[] args) { N ...

  5. Java 序列化和反序列化(二)Serializable 源码分析 - 1

    目录 Java 序列化和反序列化(二)Serializable 源码分析 - 1 1. Java 序列化接口 2. ObjectOutputStream 源码分析 2.1 ObjectOutputSt ...

  6. 如何分析SpringBoot源码模块及结构?--SpringBoot源码(二)

    注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 如何搭建自己的SpringBoot源码调试环境?--SpringBoot源码(一). 前面搭建好了自己本地的S ...

  7. k8s client-go源码分析 informer源码分析(2)-初始化与启动分析

    k8s client-go源码分析 informer源码分析(2)-初始化与启动分析 前面一篇文章对k8s informer做了概要分析,本篇文章将对informer的初始化与启动进行分析. info ...

  8. 【一起学源码-微服务】Nexflix Eureka 源码十三:Eureka源码解读完结撒花篇~!

    前言 想说的话 [一起学源码-微服务-Netflix Eureka]专栏到这里就已经全部结束了. 实话实说,从最开始Eureka Server和Eureka Client初始化的流程还是一脸闷逼,到现 ...

  9. 【一起学源码-微服务】Eureka+Ribbon+Feign阶段性总结

    前言 想说的话 这里已经梳理完Eureka.Ribbon.Feign三大组件的基本原理了,今天做一个总结,里面会有一个比较详细的调用关系流程图. 说明 原创不易,如若转载 请标明来源! 博客地址:一枝 ...

随机推荐

  1. Python神坑:sum和numpy.sum

    同样的一段代码,在两个python文件里面执行的结果不一样,一个是按照列单位进行sum一个是所有元素进行sum: def distCal(vecA, vecB): return sqrt(sum(po ...

  2. 【mybatis】之trim

    <trim prefix="where" prefixOverrides="where" suffixOverrides="and"& ...

  3. Pymysql部分

    安装: 1 执行SQL import pymysql # 创建连接 conn = pymysql.connect(host='172.30.2.233', port=3306, user='root' ...

  4. delphi combobox屏蔽鼠标滑动

    //第1种方法 procedure TForm1.FormMouseWheel(Sender: TObject; Shift: TShiftState; WheelDelta: Integer; Mo ...

  5. Java虚拟机--------JVM常见参数

    JVM 调优常见参数 Java1.7的jvm参数查看一下官方网站. http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java. ...

  6. Vue 封装js 并 引用

    /封装模块化文件 新建的.js文件 var storage = { set(key, value) { localStorage.setItem(key, JSON.stringify(value)) ...

  7. XAMPP 虚拟主机配置,实现多域名访问本地项目

    XAMPP 虚拟主机配置,实现多域名访问本地项目 1.首先你既然要配置多个虚拟主机,那你肯定需要多个站点的目录文件.你可以在e盘创建 www文件夹,然后在该文件件中新建两个站点目录,假设test.co ...

  8. svn Advanced

    1.Eclipse last 1.Eclipse 安装subversive插件: 安装连接器: 打开视图"SVN Repositories": 创建“资源库位置”: 配置全局范围文 ...

  9. Jvm的体系结构

    1.垃圾回收器 垃圾回收器(又称为gc):是负责回收内存中无用的对象(好像地球人都知道),就是这些对象没有任何引用了,它就会被视为:垃圾,也就被干掉了. 2.类装载子系统 一听名字,大家就知道,肯定是 ...

  10. 判断是否某App

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <meta name= ...