Example #1
0
 /**
  * 该worker进程开始服务的时候会触发一次
  * @return bool
  */
 protected function onServe()
 {
     // 文件更新相关 mac不支持inotify 用这个进程监控 500ms检测一次
     if (!Inotify::isSuport() && PHPServerConfig::get('ENV') == 'dev') {
         $this->eventLoopName = 'Select';
         // 安装信号处理函数
         $this->installSignal();
         $this->event = new $this->eventLoopName();
         if ($this->protocol == 'udp') {
             // 添加读udp事件
             $this->event->add($this->mainSocket, BaseEvent::EV_ACCEPT, array($this, 'recvUdp'));
         } else {
             // 添加accept事件
             $this->event->add($this->mainSocket, BaseEvent::EV_ACCEPT, array($this, 'accept'));
         }
         // 添加管道可读事件
         $this->event->add($this->channel, BaseEvent::EV_READ, array($this, 'dealCmd'), 0, 0);
         // 增加select超时事件
         $this->event->add(0, Select::EV_SELECT_TIMEOUT, array($this, 'checkFilesModify'), array(), 500);
         // 主体循环
         while (1) {
             $ret = $this->event->loop();
             $this->notice("evet->loop returned " . var_export($ret, true));
         }
         return true;
     }
 }
Example #2
0
 /**
  * 初始化
  * @return NULL
  */
 public static function init()
 {
     self::$inotifySuport = extension_loaded('inotify');
     if (!self::$inotifySuport) {
         return null;
     }
     self::$inotifyFd = inotify_init();
     stream_set_blocking(self::$inotifyFd, 0);
     return self::$inotifyFd;
 }
Example #3
0
 /**
  * 上报包含文件到监控进程
  * @param array $files
  */
 public static function reportIncludedFiles($worker_files_map)
 {
     //非开发环境或者安装了inotify扩展直接返回
     if (PHPServerConfig::get('ENV') !== 'dev' || Inotify::isSuport()) {
         return;
     }
     if ($worker_files_map && is_array($worker_files_map)) {
         $files = array();
         foreach ($worker_files_map as $worker_name => $files_array) {
             foreach ($files_array as $file) {
                 $files[$file] = $file;
             }
         }
         if ($files) {
             return self::sendData(self::CMD_TELL_INCLUDE_FILES, array_values($files));
         }
     }
 }
Example #4
0
 /**
  * 处理命令
  * @param char $cmd
  * @param mix $result
  * @param int $pid
  */
 protected static function dealCmd($cmd, $result, $pid)
 {
     // 获得所有pid到worker_name映射关系
     $all_pid_and_worker = self::getPidWorkerNameMap();
     $worker_name = isset($all_pid_and_worker[$pid]) ? $all_pid_and_worker[$pid] : '';
     switch ($cmd) {
         // 监控worker的使用的文件
         case Cmd::CMD_REPORT_INCLUDE_FILE:
             if (is_array($result)) {
                 if (empty($worker_name)) {
                     self::notice("CMD_REPORT_INCLUDE_FILE pid:{$pid} has no worker_name");
                     return false;
                 }
                 // 获取已经监控的文件
                 $all_inotify_files = self::getFilesWorkerNameMap();
                 // 获取master进程使用的文件
                 $master_included_files = array_flip(get_included_files());
                 // 遍历worker上报的包含文件
                 foreach ($result as $file) {
                     // 过滤master进程包含的文件,没有监控的文件加入监控
                     if (!isset($all_inotify_files[$file]) && !isset($master_included_files[$file])) {
                         self::$filesToInotify[$worker_name][$file] = $file;
                         if (Inotify::isSuport()) {
                             Inotify::addFile($file);
                         }
                     }
                 }
                 return true;
             }
             break;
             // 停止服务
         // 停止服务
         case Cmd::CMD_STOP_SERVE:
             // self::$event->delAll(self::$channels[$pid]);
             break;
             // 测试命令
         // 测试命令
         case Cmd::CMD_TEST:
             break;
             // 重启命令
         // 重启命令
         case Cmd::CMD_RESTART:
             // self::$event->delAll(self::$channels[$pid]);
             break;
             // telnet报告worker状态
         // telnet报告worker状态
         case Cmd::CMD_REPORT_STATUS_FOR_MASTER:
             $workers = PHPServerConfig::get('workers');
             $port = isset($workers[$worker_name]['port']) ? $workers[$worker_name]['port'] : 'none';
             $proto = isset($workers[$worker_name]['protocol']) ? $workers[$worker_name]['protocol'] : 'none';
             $str = "{$pid}\t" . str_pad(round($result['memory'] / (1024 * 1024), 2) . "M", 9) . " {$proto}    " . str_pad($port, 5) . " " . $result['start_time'] . " " . str_pad($worker_name, self::$maxWorkerNameLength) . " ";
             if ($result) {
                 $str = $str . str_pad($result['total_request'], 14) . " " . str_pad($result['recv_timeout'], 12) . " " . str_pad($result['proc_timeout'], 12) . " " . str_pad($result['packet_err'], 10) . " " . str_pad($result['thunder_herd'], 12) . " " . str_pad($result['client_close'], 12) . " " . str_pad($result['send_fail'], 9) . " " . str_pad($result['throw_exception'], 15) . " " . ($result['total_request'] == 0 ? 100 : round(($result['total_request'] - ($result['proc_timeout'] + $result['packet_err'] + $result['send_fail'])) / $result['total_request'], 6) * 100) . "%";
             } else {
                 $str .= var_export($result, true);
             }
             Telnet::sendToClient($str . "\n");
             break;
             // 心跳包回复
         // 心跳包回复
         case Cmd::CMD_PONG:
             self::$pingInfo[$pid] = 0;
             break;
             // 未知命令
         // 未知命令
         case Cmd::CMD_UNKNOW:
             break;
     }
 }