示例#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('Log')) {
         \Man\Core\Lib\Log::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);
     return true;
 }
示例#2
0
 /**
  * 处理业务
  * @see Worker::dealProcess()
  */
 public function dealProcess($buffer)
 {
     $buffer = trim($buffer);
     $ip = $this->getRemoteIp();
     if ($ip != '127.0.0.1' && $buffer == 'status') {
         \Man\Core\Lib\Log::add("IP:{$ip} {$buffer}");
     }
     // 判断是否认证过
     $this->adminAuth[$this->currentDealFd] = !isset($this->adminAuth[$this->currentDealFd]) ? 0 : $this->adminAuth[$this->currentDealFd];
     if ($this->adminAuth[$this->currentDealFd] < 3) {
         if ($buffer != \Man\Core\Lib\Config::get($this->workerName . '.password')) {
             if (++$this->adminAuth[$this->currentDealFd] >= 3) {
                 $this->sendToClient("Password Incorrect \n");
                 $this->closeClient($this->currentDealFd);
                 return;
             }
             $this->sendToClient("Please Try Again\n");
             return;
         } else {
             $this->adminAuth[$this->currentDealFd] = time();
             $this->sendToClient("Hello Admin \n");
             return;
         }
     }
     // 单独停止某个worker进程
     if (preg_match("/kill (\\d+)/", $buffer, $match)) {
         $pid = $match[1];
         $this->sendToClient("Kill Pid {$pid}\n");
         if (!posix_kill($pid, SIGHUP)) {
             $this->sendToClient("Pid Not Exsits\n");
         }
         return;
     }
     $master_pid = file_get_contents(WORKERMAN_PID_FILE);
     switch ($buffer) {
         // 展示统计信息
         case 'status':
             $status = $this->getMasterStatus();
             if (empty($status)) {
                 $this->sendToClient("Can not get Master status, Extension sysvshm or sysvmsg may not enabled\n");
                 return;
             }
             $worker_pids = $this->getWorkerPidMap();
             $pid_worker_name_map = $this->getPidWorkerMap();
             foreach ($worker_pids as $worker_name => $pid_array) {
                 if ($this->maxWorkerNameLength < strlen($worker_name)) {
                     $this->maxWorkerNameLength = strlen($worker_name);
                 }
             }
             foreach (\Man\Core\Lib\Config::getAllWorkers() as $worker_name => $config) {
                 if (!isset($config['listen'])) {
                     continue;
                 }
                 if ($this->maxAddressLength < strlen($config['listen'])) {
                     $this->maxAddressLength = strlen($config['listen']);
                 }
             }
             $msg_type = $message = 0;
             // 将过期的消息读出来,清理掉
             if (\Man\Core\Master::getQueueId()) {
                 while (@msg_receive(\Man\Core\Master::getQueueId(), self::MSG_TYPE_STATUS, $msg_type, 1000, $message, true, MSG_IPC_NOWAIT)) {
                 }
             }
             $loadavg = sys_getloadavg();
             $this->sendToClient("---------------------------------------GLOBAL STATUS--------------------------------------------\n");
             $this->sendToClient(\Man\Core\Master::NAME . ' version:' . \Man\Core\Master::VERSION . "\n");
             $this->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");
             $this->sendToClient('load average: ' . implode(", ", $loadavg) . "\n");
             $this->sendToClient(count($this->connections) . ' users          ' . count($worker_pids) . ' workers       ' . count($pid_worker_name_map) . " processes\n");
             $this->sendToClient(str_pad('worker_name', $this->maxWorkerNameLength) . " exit_status     exit_count\n");
             foreach ($worker_pids as $worker_name => $pid_array) {
                 if (isset($status['worker_exit_code'][$worker_name])) {
                     foreach ($status['worker_exit_code'][$worker_name] as $exit_status => $exit_count) {
                         $this->sendToClient(str_pad($worker_name, $this->maxWorkerNameLength) . " " . str_pad($exit_status, 16) . " {$exit_count}\n");
                     }
                 } else {
                     $this->sendToClient(str_pad($worker_name, $this->maxWorkerNameLength) . " " . str_pad(0, 16) . " 0\n");
                 }
             }
             $this->sendToClient("---------------------------------------PROCESS STATUS-------------------------------------------\n");
             $this->sendToClient("pid\tmemory  " . str_pad('    listening', $this->maxAddressLength) . " timestamp  " . str_pad('worker_name', $this->maxWorkerNameLength) . " " . str_pad('total_request', 13) . " " . 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");
             if (!\Man\Core\Master::getQueueId()) {
                 return;
             }
             $time_start = time();
             unset($pid_worker_name_map[posix_getpid()]);
             $total_worker_count = count($pid_worker_name_map);
             foreach ($pid_worker_name_map as $pid => $worker_name) {
                 posix_kill($pid, SIGUSR1);
                 if ($this->getStatusFromQueue()) {
                     $total_worker_count--;
                 }
             }
             while ($total_worker_count > 0) {
                 if ($this->getStatusFromQueue()) {
                     $total_worker_count--;
                 }
                 if (time() - $time_start > 1) {
                     break;
                 }
             }
             break;
             // 停止server
         // 停止server
         case 'stop':
             if ($master_pid) {
                 $this->sendToClient("stoping....\n");
                 posix_kill($master_pid, SIGINT);
             } else {
                 $this->sendToClient("Can not get master pid\n");
             }
             break;
             // 平滑重启server
         // 平滑重启server
         case 'reload':
             $pid_worker_name_map = $this->getPidWorkerMap();
             unset($pid_worker_name_map[posix_getpid()]);
             if ($pid_worker_name_map) {
                 foreach ($pid_worker_name_map as $pid => $item) {
                     posix_kill($pid, SIGHUP);
                 }
                 $this->sendToClient("Restart Workers\n");
             } else {
                 if ($master_pid) {
                     posix_kill($master_pid, SIGHUP);
                     $this->sendToClient("Restart Workers\n");
                 } else {
                     $this->sendToClient("Can not get master pid\n");
                 }
             }
             break;
             // admin管理员退出
         // admin管理员退出
         case 'quit':
             $this->sendToClient("Admin Quit\n");
             $this->closeClient($this->currentDealFd);
             break;
         case '':
             break;
         default:
             $this->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");
     }
 }
示例#3
0
 /**
  * 检查文件更新时间,如果有更改则平滑重启服务(开发的时候用到)
  * @return void
  */
 public function checkFilesModify()
 {
     $has_send_signal = false;
     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) {
             $this->filesToInotify[$file] = $mtime_now;
             if (!$has_send_signal) {
                 \Man\Core\Lib\Log::add("{$file} updated and reload workers");
                 $this->sendSignalToAllWorker(SIGHUP);
                 $has_send_signal = true;
             }
         }
     }
 }
示例#4
0
 /**
  * 记录日志
  * @param sring $str
  * @return void
  */
 protected function notice($str, $display = true)
 {
     $str = 'Worker[' . get_class($this) . ':' . posix_getpid() . ']:' . $str;
     Log::add($str);
     if ($display && Config::get('workerman.debug') == 1) {
         echo $str . "\n";
     }
 }
示例#5
0
 /**
  * notice,记录到日志
  * @param string $msg
  * @param bool $display
  * @return void
  */
 public static function notice($msg, $display = false)
 {
     Log::add("Server:" . trim($msg));
     if ($display) {
         if (self::$serviceStatus == self::STATUS_STARTING && @posix_ttyname(STDOUT)) {
             echo $msg . "\n";
         }
     }
 }