Exemplo n.º 1
0
 /**
  * 
  * 添加一个任务
  * 
  * @param int $time_long 多长时间运行一次 单位秒
  * @param callback $func 任务运行的函数或方法
  * @param mix $args 任务运行的函数或方法使用的参数
  * @return void
  */
 public static function add($time_long, $func, $args = array(), $persistent = true)
 {
     if ($time_long <= 0) {
         return false;
     }
     if (!is_callable($func) && class_exists('ServerLog')) {
         ServerLog::add(var_export($func, true) . "not callable\n");
         return false;
     }
     $time_now = time();
     $run_time = $time_now + $time_long;
     if (!isset(self::$tasks[$run_time])) {
         self::$tasks[$run_time] = array();
     }
     self::$tasks[$run_time][] = array($func, $args, $persistent, $time_long);
 }
Exemplo n.º 2
0
 /**
  * debug
  * @param sring $str
  */
 protected function notice($str)
 {
     ServerLog::add('[' . get_class($this) . '] ' . $str);
 }
Exemplo n.º 3
0
 /**
  * notice,记录到日志,同时打印到telnet客户端(如果有telnet链接的话)
  * @param string $msg
  * @param bool $display
  */
 protected static function notice($msg, $display = false)
 {
     ServerLog::add("Server notice:" . $msg);
     Telnet::sendToAllClient($msg . "\n");
     if ($display) {
         if (self::$serverStatus == self::STATUS_STARTING) {
             echo $msg . "\n";
         }
     }
 }
Exemplo n.º 4
0
 /**
  * 处理收到的管理员命令
  * @param event_buffer $event_buffer
  * @param int $fd
  * @return boolean
  */
 public static function dealCmd($connection, $length, $buffer, $fd = null)
 {
     // 管理员断开
     if ($length == 0) {
         self::closeClient($fd);
         return;
     }
     self::$currentFd = $fd;
     $buffer = trim($buffer);
     $ip = self::getRemoteIp();
     if ($ip != '127.0.0.1' && $buffer == 'status') {
         ServerLog::add("IP:{$ip} {$buffer}");
     }
     // 判断是否认证过
     self::$adminAuth[$fd] = !isset(self::$adminAuth[$fd]) ? 0 : self::$adminAuth[$fd];
     if (self::$adminAuth[$fd] < 3) {
         if ($buffer != 'P@ssword') {
             if (++self::$adminAuth[$fd] >= 3) {
                 self::sendToClient("Password Incorrect \n");
                 self::closeClient($fd);
             }
             self::sendToClient("Please Try Again\n");
             return;
         } else {
             self::$adminAuth[$fd] = time();
             self::sendToClient("Hello Admin \n");
             return;
         }
     }
     $pid_worker_name_map = PHPServer::getPidWorkerNameMap();
     // 单独停止某个worker进程
     if (preg_match("/kill (\\d+)/", $buffer, $match)) {
         $pid = $match[1];
         if (isset($pid_worker_name_map[$pid])) {
             self::sendToClient("Kill Pid {$pid} ");
             PHPServer::addToRestartWorkers(array($pid));
             PHPServer::restartWorkers();
         } else {
             self::sendToClient("Pid Not Exsits\n");
         }
         return;
     }
     // 打印某个变量 print_r $current
     if (preg_match("/debug (.*)/", $buffer, $match)) {
         $var = trim($match[1]);
         $var = str_replace('$', '', $var);
         if (!$var) {
             self::sendToClient("Uesage debug var_name\n");
             return;
         }
         self::sendToClient(PHPServer::debugVar($var) . "\n");
         return;
     }
     switch ($buffer) {
         // 展示统计信息
         case 'status':
             $status = PHPServer::getServerStatusInfo();
             $worker_pids = PHPServer::getWorkerPids();
             $loadavg = sys_getloadavg();
             self::sendToClient("---------------------------------------GLOBAL STATUS--------------------------------------------\n");
             self::sendToClient('start time:' . date('Y-m-d H:i:s', $status['start_time']) . '   run ' . floor((time() - $status['start_time']) / (24 * 60 * 60)) . ' days ' . floor((time() - $status['start_time']) % (24 * 60 * 60) / (60 * 60)) . " hours   \n");
             self::sendToClient('load average: ' . implode(", ", $loadavg) . "\n");
             self::sendToClient(count(self::$connections) . ' users          ' . count($worker_pids) . ' workers       ' . count($pid_worker_name_map) . " processes\n");
             self::sendToClient(str_pad('worker_name', self::$maxWorkerNameLength) . " exit_status     exit_count\n");
             foreach ($worker_pids as $worker_name => $pid_array) {
                 if (isset($status['err_info'][$worker_name])) {
                     foreach ($status['err_info'][$worker_name] as $exit_status => $exit_count) {
                         self::sendToClient(str_pad($worker_name, self::$maxWorkerNameLength) . " " . str_pad($exit_status, 16) . " {$exit_count}\n");
                     }
                 } else {
                     self::sendToClient(str_pad($worker_name, self::$maxWorkerNameLength) . " " . str_pad(0, 16) . " 0\n");
                 }
             }
             PHPServer::sendCmdToAll(Cmd::CMD_REPORT_STATUS_FOR_MASTER);
             self::sendToClient("---------------------------------------PROCESS STATUS-------------------------------------------\n");
             self::sendToClient("pid\tmemory    proto  port  timestamp  " . str_pad('worker_name', self::$maxWorkerNameLength) . " " . str_pad('total_request', 13) . " " . str_pad('recv_timeout', 12) . " " . str_pad('proc_timeout', 12) . " " . str_pad('packet_err', 10) . " " . str_pad('thunder_herd', 12) . " " . str_pad('client_close', 12) . " " . str_pad('send_fail', 9) . " " . str_pad('throw_exception', 15) . " suc/total\n");
             break;
             // 停止server
         // 停止server
         case 'stop':
             PHPServer::stop();
             break;
             // 平滑重启server
         // 平滑重启server
         case 'reload':
             PHPServer::addToRestartWorkers(array_keys($pid_worker_name_map));
             PHPServer::restartWorkers();
             self::sendToClient("Restart Workers ");
             break;
             // admin管理员退出
         // admin管理员退出
         case 'quit':
             self::sendToClient("Admin Quit\n");
             self::$event->delAll(self::$connections[self::$currentFd]);
             fclose(self::$connections[self::$currentFd]);
             unset(self::$connections[self::$currentFd], self::$adminAuth[self::$currentFd]);
             break;
         case 'debug':
             self::sendToClient("Uesage debug var_name\n");
             break;
         case '':
             break;
         default:
             self::sendToClient("Unkonw CMD \nAvailable CMD:\n status     show server status\n stop       stop server\n reload     graceful restart server\n quit       quit and close connection\n kill pid   kill the worker process of the pid\n");
     }
 }
Exemplo n.º 5
0
 public function onAlarm()
 {
     $ob_content = ob_get_contents();
     if ($ob_content) {
         ServerLog::add('StatisticService:ob_content:' . $ob_content);
         ob_clean();
     }
 }
Exemplo n.º 6
0
 /**
  * 检查文件更新时间,如果有更改则平滑重启服务(开发的时候用到)
  * @return void
  */
 public function checkFilesModify()
 {
     if ($this->isReloading) {
         return;
     }
     foreach ($this->filesToInotify as $file => $mtime) {
         clearstatcache();
         $stat = @stat($file);
         if (false === $stat) {
             unset($this->filesToInotify[$file]);
             continue;
         }
         $mtime_now = $stat['mtime'];
         if ($mtime != $mtime_now) {
             ServerLog::add("{$file} updated and reload workers");
             $master_pid = file_get_contents(PID_FILE);
             if ($master_pid) {
                 posix_kill($master_pid, SIGUSR2);
                 $this->isReloading = true;
             }
         }
     }
 }