/**
  * 让该worker实例开始服务
  *
  * @param bool $is_daemon 告诉 Worker 当前是否运行在 daemon 模式, 非 daemon 模式不拦截 signals
  * @return void
  */
 public function serve($is_daemon = true)
 {
     // 触发该worker进程onServe事件,该进程整个生命周期只触发一次
     if ($this->onServe()) {
         return;
     }
     // 安装信号处理函数
     if ($is_daemon === true) {
         $this->installSignal();
     }
     // 初始化事件轮询库
     $this->event = new $this->eventLoopName();
     // 添加accept事件
     $this->event->add($this->mainSocket, BaseEvent::EV_ACCEPT, array($this, 'accept'));
     // 添加管道可读事件
     $this->event->add($this->channel, BaseEvent::EV_READ, array($this, 'dealCmd'), null, 0, 0);
     // 监听一个udp端口,用来广播ip
     $error_no = 0;
     $error_msg = '';
     // 创建监听socket
     $this->udpBroadSocket = @stream_socket_server('udp://0.0.0.0:' . PHPServerConfig::get('workers.' . $this->serviceName . '.port'), $error_no, $error_msg, STREAM_SERVER_BIND);
     if ($this->udpBroadSocket) {
         $this->event->add($this->udpBroadSocket, BaseEvent::EV_ACCEPT, array($this, 'recvBroadcastUdp'));
     }
     // 主体循环
     $ret = $this->event->loop();
     $this->notice("evet->loop returned " . var_export($ret, true));
     exit(self::EXIT_UNEXPECT_CODE);
 }
Exemple #2
0
 /**
  * 该worker进程开始服务的时候会触发一次
  * @return bool
  */
 protected function onServe()
 {
     $this->eventLoopName = 'Select';
     $time_interval = PHPServerConfig::get('workers.' . $this->serviceName . '.time_interval_ms');
     if ($time_interval > 1) {
         $this->timeIntervalMS = $time_interval;
     }
     $this->installSignal();
     $this->event = new $this->eventLoopName();
     // 添加管道可读事件
     $this->event->add($this->channel, BaseEvent::EV_READ, array($this, 'dealCmd'), 0, 0);
     // 增加select超时事件
     $this->event->add(0, Select::EV_SELECT_TIMEOUT, array($this, 'onTime'), array(), $this->timeIntervalMS);
     $bootstrap = PHPServerConfig::get('workers.' . $this->serviceName . '.bootstrap');
     if (is_file($bootstrap)) {
         require_once $bootstrap;
     }
     if (function_exists('on_start')) {
         call_user_func('on_start');
     }
     $this->lastCallOnTime = microtime(true);
     // 主体循环
     while (1) {
         $ret = $this->event->loop();
         $this->notice("evet->loop returned " . var_export($ret, true));
     }
 }
Exemple #3
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;
     }
 }
Exemple #4
0
 public function onServe()
 {
     require_once SERVER_BASE . 'thirdparty/MNLogger/MNLogger.php';
     $logdir = PHPServerConfig::get('monitor_log_path') ? PHPServerConfig::get('monitor_log_path') : '/home/logs/monitor';
     $config = array('on' => true, 'app' => 'php-rpc-server', 'logdir' => $logdir);
     try {
         self::$rpcMNLogger = @thirdparty\MNLogger\MNLogger::instance($config);
     } catch (Exception $e) {
     }
     // 初始化统计上报地址
     $report_address = PHPServerConfig::get('workers.' . $this->serviceName . '.report_address');
     if ($report_address) {
         StatisticClient::config(array('report_address' => $report_address));
     } else {
         if ($config = PHPServerConfig::get('workers.StatisticWorker')) {
             if (!isset($config['ip'])) {
                 $config['ip'] = '127.0.0.1';
             }
             StatisticClient::config(array('report_address' => 'udp://' . $config['ip'] . ':' . $config['port']));
         }
     }
     // 业务引导程序bootstrap初始化(没有则忽略)
     $bootstrap = PHPServerConfig::get('workers.' . $this->serviceName . '.bootstrap');
     if (is_file($bootstrap)) {
         require_once $bootstrap;
     }
     // 服务名
     self::$appName = $this->serviceName;
 }
Exemple #5
0
 protected function process($data)
 {
     if (!class_exists('Core\\Lib\\RpcServer')) {
         $frameworkBootstrap = PHPServerConfig::get('workers.' . $this->serviceName . '.framework.path') . '/Serverroot/Autoload.php';
         require_once $frameworkBootstrap;
     }
     StatisticHelper::tick();
     $rpcServer = new Core\Lib\RpcServer();
     $ctx = $rpcServer->run($data);
     StatisticHelper::report($data, $ctx, $this->getRemoteIp());
     $this->send($ctx);
 }
Exemple #6
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));
         }
     }
 }
Exemple #7
0
 /**
  * 处理数据流.
  *
  * @param string $recv_str 接收到的数据流.
  *
  * @throws Exception 抛出开发时错误.
  *
  * @return void
  */
 public function dealProcess($recv_str)
 {
     try {
         if (($data = Text::decode($recv_str)) === false) {
             throw new Exception('RpcWorker: You want to check the RPC protocol.');
         }
         if ($data['command'] === 'TEST' && $data['data'] === 'PING') {
             $this->send('PONG');
             return;
         }
         $this->rpcCompressor = null;
         if (strpos($data['command'], 'RPC:') === 0) {
             $this->rpcCompressor = substr($data['command'], strpos($data['command'], ':') + 1);
         } elseif ($data['command'] !== 'RPC') {
             throw new Exception('RpcWorker: Oops! I am going to do nothing but RPC.');
         }
         $data = $data['data'];
         if ($this->rpcCompressor === 'GZ') {
             $data = @gzuncompress($data);
         }
         $packet = json_decode($data, true);
         if ($this->encrypt($packet['data'], PHPServerConfig::get('rpc_secret_key')) !== $packet['signature']) {
             throw new Exception('RpcWorker: You want to check the RPC secret key, or the packet has broken.');
         }
         $data = json_decode($packet['data'], true);
         if (empty($data['version']) || $data['version'] !== '1.0') {
             throw new Exception('RpcWorker: Hmm! We are now expect version 1.0.');
         }
         $prefix = 'RpcClient_';
         if (strpos($data['class'], $prefix) !== 0) {
             throw new Exception(sprintf('RpcWorker: Mmm! RPC class name should be prefix with %s.', $prefix));
         }
         $data['class'] = substr($data['class'], strlen($prefix));
         $this->process($data);
     } catch (Exception $ex) {
         $this->send(array('exception' => array('class' => get_class($ex), 'message' => $ex->getMessage(), 'code' => $ex->getCode(), 'file' => $ex->getFile(), 'line' => $ex->getLine(), 'traceAsString' => $ex->getTraceAsString())));
     }
 }
 public function getService()
 {
     $this->thriftServiceArray = array();
     $client_config = array();
     // 查看thriftWorker配置了哪些服务和ip
     foreach (PHPServerConfig::get('workers') as $worker_name => $config) {
         if ((empty($config['worker_class']) || $config['worker_class'] != 'ThriftWorker') && $worker_name != 'ThriftWorker') {
             continue;
         }
         $ip = !empty($config['ip']) ? $config['ip'] : '127.0.0.1';
         $address = "{$ip}:{$config['port']}";
         $providerNamespace = 'Provider';
         if ($provider_dir = PHPServerConfig::get('workers.' . $worker_name . '.provider')) {
             if (($provider_dir = realpath($provider_dir)) && ($path_array = explode('/', $provider_dir = realpath($provider_dir)))) {
                 $providerNamespace = $path_array[count($path_array) - 1];
             }
         }
         $handlerNamespace = 'Provider';
         if ($handler_dir = PHPServerConfig::get('workers.' . $worker_name . '.handler')) {
             if (($handler_dir = realpath($handler_dir)) && ($path_array = explode('/', $handler_dir))) {
                 $handlerNamespace = $path_array[count($path_array) - 1];
             }
         }
         if (!empty($provider_dir)) {
             foreach (glob($provider_dir . "/*", GLOB_ONLYDIR) as $dir) {
                 foreach (glob($dir . "/*.php") as $php_file) {
                     require_once $php_file;
                 }
                 $tmp_arr = explode("/", $dir);
                 $service_name = array_pop($tmp_arr);
                 if (empty($service_name)) {
                     continue;
                 }
                 if ($handlerNamespace == 'Provider') {
                     $class_name = "\\{$handlerNamespace}\\{$service_name}\\{$service_name}Handler";
                     $handler_file = $handler_dir . '/' . $service_name . '/' . $service_name . 'Handler.php';
                 } else {
                     $class_name = "\\{$handlerNamespace}\\{$service_name}";
                     $handler_file = $handler_dir . '/' . $service_name . '.php';
                 }
                 if (is_file($handler_file)) {
                     require_once $handler_file;
                 }
                 if (class_exists($class_name)) {
                     $re = new ReflectionClass($class_name);
                     $method_array = $re->getMethods(ReflectionMethod::IS_PUBLIC);
                     $this->thriftServiceArray[$service_name] = array();
                     foreach ($method_array as $m) {
                         $params_arr = $m->getParameters();
                         $method_name = $m->name;
                         $params = array();
                         foreach ($params_arr as $p) {
                             $params[] = $p->name;
                         }
                         $this->thriftServiceArray[$service_name][$method_name] = $params;
                     }
                     $client_config[$service_name] = array('nodes' => array($address), 'provider' => $provider_dir);
                 }
             }
         }
     }
     ClientForTest::config($client_config);
     return $this->thriftServiceArray;
 }
Exemple #9
0
 /**
  * 恢复标准输出(开发环境用)
  * @return void
  */
 protected static function recoverStdFd()
 {
     if (PHPServerConfig::get('ENV') == 'dev') {
         @ob_end_clean();
     }
     if (!posix_ttyname(STDOUT)) {
         global $STDOUT, $STDERR;
         @fclose(STDOUT);
         @fclose(STDERR);
         $STDOUT = fopen('/dev/null', "rw+");
         $STDERR = fopen('/dev/null', "rw+");
         return;
     }
 }
Exemple #10
0
 /**
  * 进程启动时的一些初始化
  * @see PHPServerWorker::onServe()
  */
 public function onServe()
 {
     // 初始化thrift生成文件存放目录
     $provider_dir = PHPServerConfig::get('workers.' . $this->serviceName . '.provider');
     if ($provider_dir) {
         if ($this->providerDir = realpath($provider_dir)) {
             if ($path_array = explode('/', $this->providerDir)) {
                 $this->providerNamespace = $path_array[count($path_array) - 1];
             }
         } else {
             $this->providerDir = $provider_dir;
             $this->notice('provider_dir ' . $provider_dir . ' not exsits');
         }
     }
     // 初始化thrift生成类业务实现存放目录
     $handler_dir = PHPServerConfig::get('workers.' . $this->serviceName . '.handler');
     if ($handler_dir) {
         if ($this->handlerDir = realpath($handler_dir)) {
             if ($path_array = explode('/', $this->handlerDir)) {
                 $this->handlerNamespace = $path_array[count($path_array) - 1];
             }
         } else {
             $this->handlerDir = $handler_dir;
             $this->notice('handler_dir' . $handler_dir . ' not exsits');
         }
     } else {
         $this->handlerDir = $provider_dir;
     }
     // 统一日志类初始化
     require_once SERVER_BASE . 'thirdparty/MNLogger/MNLogger.php';
     $logdir = PHPServerConfig::get('monitor_log_path') ? PHPServerConfig::get('monitor_log_path') : '/home/logs/monitor';
     $config = array('on' => true, 'app' => 'php-rpc-server', 'logdir' => $logdir);
     try {
         self::$rpcMNLogger = @thirdparty\MNLogger\MNLogger::instance($config);
     } catch (Exception $e) {
     }
     // 初始化统计上报地址
     $report_address = PHPServerConfig::get('workers.' . $this->serviceName . '.report_address');
     if ($report_address) {
         StatisticClient::config(array('report_address' => $report_address));
     } else {
         if ($config = PHPServerConfig::get('workers.StatisticWorker')) {
             if (!isset($config['ip'])) {
                 $config['ip'] = '127.0.0.1';
             }
             StatisticClient::config(array('report_address' => 'udp://' . $config['ip'] . ':' . $config['port']));
         }
     }
     // 业务引导程序bootstrap初始化(没有则忽略)
     $bootstrap = PHPServerConfig::get('workers.' . $this->serviceName . '.bootstrap');
     if (is_file($bootstrap)) {
         require_once $bootstrap;
     }
     // 服务名
     self::$appName = $this->serviceName;
 }
Exemple #11
0
 /**
  * 获取本地ip,优先获取JumeiWorker配置的ip
  * @param string $worker_name
  * @return string
  */
 public function getIp($worker_name = 'JumeiWorker')
 {
     $ip = $this->getLocalIp();
     if (empty($ip) || $ip == '0.0.0.0' || ($ip = '127.0.0.1')) {
         if ($worker_name) {
             $ip = PHPServerConfig::get('workers.' . $worker_name . '.ip');
         }
         if (empty($ip) || $ip == '0.0.0.0' || ($ip = '127.0.0.1')) {
             $ret_string = shell_exec('ifconfig');
             if (preg_match("/:(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})/", $ret_string, $match)) {
                 $ip = $match[1];
             }
         }
     }
     return $ip;
 }
Exemple #12
0
 protected function getStasticLog($module, $interface, $start_time, $end_time = '', $code = '', $msg = '', $pointer = '', $count = 10)
 {
     $pack = new JMProtocol();
     $pack->header['cmd'] = self::CMD_PROVIDER;
     $pack->header['sub_cmd'] = self::SUB_CMD_GET_LOGS;
     $ip_list = !empty($_GET['ip']) && is_array($_GET['ip']) ? $_GET['ip'] : $this->phpServerIpList;
     $pointer_list = !empty($_GET['pointer']) && is_array($_GET['pointer']) ? $_GET['pointer'] : array();
     $port = PHPServerConfig::get('workers.StatisticProvider.port');
     $request_buffer_array = array();
     foreach ($ip_list as $key => $ip) {
         $pointer = isset($pointer_list[$key]) ? $pointer_list[$key] : 0;
         $pack->body = json_encode(array('module' => $module, 'interface' => $interface, 'start_time' => $start_time, 'end_time' => $end_time, 'code' => $code, 'msg' => $msg, 'pointer' => $pointer, 'count' => $count));
         $request_buffer_array["{$ip}:{$port}"] = $pack->getBuffer();
     }
     $read_buffer_array = $this->multiRequest($request_buffer_array);
     ksort($read_buffer_array);
     foreach ($read_buffer_array as $address => $buf) {
         list($ip, $port) = explode(':', $address);
         $pack = new JMProtocol($buf);
         $body_data = json_decode($pack->body, true);
         $log_data = isset($body_data['data']) ? $body_data['data'] : '';
         $point = isset($body_data['pointer']) ? $body_data['pointer'] : 0;
         $read_buffer_array[$address] = array('pointer' => $point, 'data' => $log_data);
     }
     return $read_buffer_array;
 }
 protected function getAddress()
 {
     $address_array = array();
     foreach (PHPServerConfig::get('workers') as $service_name => $config) {
         if (!empty($config['worker_class']) && ($config['worker_class'] == 'JumeiWorker' || $config['worker_class'] == 'JmTextWorker') || $service_name == 'JumeiWorker' || $service_name == 'JmTextWorker') {
             $ip = '127.0.0.1';
             $address_array["{$ip}:{$config['port']}"] = "{$ip}:{$config['port']} {$service_name}";
         }
     }
     return empty($address_array) ? $address_array = array('127.0.0.1:2201' => '127.0.0.1:2201 JumeiWorker') : $address_array;
 }