• 二 分析easyswoole源码(启动服务)


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

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

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

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

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

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

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

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

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

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

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

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

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

     

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

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

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

      

  • 相关阅读:
    Welcome to Swift (苹果官方Swift文档初译与注解十一)---70~76页(第二章)
    Welcome to Swift (苹果官方Swift文档初译与注解十)---63~69页(第二章)
    Welcome to Swift (苹果官方Swift文档初译与注解九)---58~62页(第二章)
    Welcome to Swift (苹果官方Swift文档初译与注解六)---35~44页 (第一章完)
    CSS3如何实现2D转换和3D转换,他们有何区别
    表格列布局系列如何灵活把握列宽
    如何将多行数据以分组的形式对齐到单元格的上,中或下位置
    媒体查询的应用以及在css3中的变革
    样式表优先级顺序
    创建热点区域
  • 原文地址:https://www.cnblogs.com/gavinjunftd/p/9430971.html
Copyright © 2020-2023  润新知