예제 #1
0
 /**
  * 进程启动时初始化
  * @see Man\Core.SocketWorker::onStart()
  */
 protected function onStart()
 {
     // 定时检查与gateway进程的连接
     \Man\Core\Lib\Task::init($this->event);
     \Man\Core\Lib\Task::add(1, array($this, 'checkGatewayConnections'));
     $this->checkGatewayConnections();
     Gateway::setBusinessWorker($this);
 }
예제 #2
0
 public function onStart()
 {
     // 初始化定时任务,让$this->event负责定时触发
     \Man\Core\Lib\Task::init($this->event);
     // 定时任务1的时间间隔2秒
     $time_interval1 = 2;
     // 设定定时任务
     \Man\Core\Lib\Task::add($time_interval1, function () {
         // 任务逻辑
         //echo 11 . PHP_EOL;
     });
     // 定时任务2的时间间隔10秒
     $time_interval2 = 10;
     // 设定定时任务,定时运行 $this->dealProcess();
     \Man\Core\Lib\Task::add($time_interval2, array($this, 'taskTwo'));
 }
예제 #3
0
 /**
  * 该worker进程开始服务的时候会触发一次
  * @return bool
  */
 public function start()
 {
     if (\Man\Core\Lib\Config::get('workerman.debug') != 1 || !\Man\Core\Master::getQueueId()) {
         while (1) {
             if (!$this->hasShutDown()) {
                 sleep(PHP_INT_MAX);
             } else {
                 exit(0);
             }
         }
     }
     $msg_type = $message = 0;
     \Man\Core\Lib\Task::init();
     \Man\Core\Lib\Task::add(1, array($this, 'sendSignalAndGetResult'));
     \Man\Core\Lib\Task::add(1, array($this, 'checkFilesModify'));
     \Man\Core\Lib\Task::add(1, array($this, 'checkTty'));
     while (1) {
         $this->collectFiles(true);
         if ($this->hasShutDown()) {
             exit(0);
         }
     }
     return true;
 }
예제 #4
0
 /**
  * 该进程开始服务
  * @see SocketWorker::start()
  */
 public function start()
 {
     // 安装信号
     $this->installSignal();
     // 初始化任务
     \Man\Core\Lib\Task::init($this->event);
     \Man\Core\Lib\Task::add(self::CLEAR_LOGS_TIME_LONG, array($this, 'clearLogs'), array(WORKERMAN_LOG_DIR));
     \Man\Core\Lib\Task::add(self::CHECK_MASTER_PROCESS_TIME_LONG, array($this, 'checkMasterProcess'));
     \Man\Core\Lib\Task::add(self::CHECK_MASTER_STATUS_TIME_LONG, array($this, 'checkMasterStatus'));
     \Man\Core\Lib\Task::add(self::CHECK_MASTER_STATUS_TIME_LONG, array($this, 'checkMemUsage'));
     // 添加accept事件
     $this->event->add($this->mainSocket, \Man\Core\Events\BaseEvent::EV_READ, array($this, 'onAccept'));
     // 主体循环
     $ret = $this->event->loop();
 }
예제 #5
0
 /**
  * 服务运行
  * @return void
  */
 public static function run()
 {
     // 输出信息
     self::notice("Workerman is starting ...", true);
     // 初始化
     self::init();
     // 检查环境
     self::checkEnv();
     // 变成守护进程
     self::daemonize();
     // 保存进程pid
     self::savePid();
     // 安装信号
     self::installSignal();
     // 创建监听套接字
     self::createListeningSockets();
     // 创建worker进程
     self::spawnWorkers();
     // 输出信息
     self::notice("\nWorkerman start success ...", true);
     // 标记服务状态为运行中
     self::$serviceStatus = self::STATUS_RUNNING;
     // 初始化任务
     \Man\Core\Lib\Task::init();
     // 关闭标准输出
     self::resetStdFd();
     // 主循环
     self::loop();
 }
예제 #6
0
 /**
  * 初始化
  * 统计目录检查
  * 初始化任务
  * @see Man\Core.SocketWorker::onStart()
  */
 protected function onStart()
 {
     // 初始化目录
     umask(0);
     $statistic_dir = WORKERMAN_LOG_DIR . $this->statisticDir;
     if (!is_dir($statistic_dir)) {
         mkdir($statistic_dir, 0777, true);
     }
     $log_dir = WORKERMAN_LOG_DIR . $this->logDir;
     if (!is_dir($log_dir)) {
         mkdir($log_dir, 0777, true);
     }
     // 初始化任务
     \Man\Core\Lib\Task::init($this->event);
     // 定时保存统计数据
     \Man\Core\Lib\Task::add(self::WRITE_PERIOD_LENGTH, array($this, 'writeStatisticsToDisk'));
     \Man\Core\Lib\Task::add(self::WRITE_PERIOD_LENGTH, array($this, 'writeLogToDisk'));
     // 定时清理不用的统计数据
     \Man\Core\Lib\Task::add(self::CLEAR_PERIOD_LENGTH, array($this, 'clearDisk'), array(WORKERMAN_LOG_DIR . $this->statisticDir, self::EXPIRED_TIME));
     \Man\Core\Lib\Task::add(self::CLEAR_PERIOD_LENGTH, array($this, 'clearDisk'), array(WORKERMAN_LOG_DIR . $this->logDir, self::EXPIRED_TIME));
 }
예제 #7
0
 /**
  * 进程启动
  */
 public function start()
 {
     // 安装信号处理函数
     $this->installSignal();
     // 添加accept事件
     $ret = $this->event->add($this->mainSocket, Man\Core\Events\BaseEvent::EV_READ, array($this, 'accept'));
     // 创建内部通信套接字,用于与BusinessWorker通讯
     $start_port = Man\Core\Lib\Config::get($this->workerName . '.lan_port_start');
     // 计算本进程监听的ip端口
     if (strpos(\Man\Core\Master::VERSION, 'mt')) {
         $this->lanPort = $start_port + \Thread::getCurrentThreadId() % 100;
     } else {
         $this->lanPort = $start_port - posix_getppid() + posix_getpid();
     }
     // 如果端口不在合法范围
     if ($this->lanPort < 0 || $this->lanPort >= 65535) {
         $this->lanPort = rand($start_port, 65535);
     }
     // 如果
     $this->lanIp = Man\Core\Lib\Config::get($this->workerName . '.lan_ip');
     if (!$this->lanIp) {
         $this->notice($this->workerName . '.lan_ip not set');
         $this->lanIp = '127.0.0.1';
     }
     $error_no_udp = $error_no_tcp = 0;
     $error_msg_udp = $error_msg_tcp = '';
     // 执行监听
     $this->innerMainSocketUdp = stream_socket_server("udp://" . $this->lanIp . ':' . $this->lanPort, $error_no_udp, $error_msg_udp, STREAM_SERVER_BIND);
     $this->innerMainSocketTcp = stream_socket_server("tcp://" . $this->lanIp . ':' . $this->lanPort, $error_no_tcp, $error_msg_tcp, STREAM_SERVER_BIND | STREAM_SERVER_LISTEN);
     // 出错,退出,下次会换个端口
     if (!$this->innerMainSocketUdp || !$this->innerMainSocketTcp) {
         $this->notice('create innerMainSocket udp or tcp fail and exit ' . $error_msg_udp . $error_msg_tcp);
         $this->stop();
     } else {
         stream_set_blocking($this->innerMainSocketUdp, 0);
         stream_set_blocking($this->innerMainSocketTcp, 0);
     }
     // 注册套接字
     if (!$this->registerAddress($this->lanIp . ':' . $this->lanPort)) {
         $this->notice('registerAddress fail and exit');
         $this->stop();
     }
     // 添加读udp/tcp事件
     $this->event->add($this->innerMainSocketUdp, Man\Core\Events\BaseEvent::EV_READ, array($this, 'recvInnerUdp'));
     $this->event->add($this->innerMainSocketTcp, Man\Core\Events\BaseEvent::EV_READ, array($this, 'acceptInnerTcp'));
     // 初始化心跳包时间间隔
     $ping_interval = \Man\Core\Lib\Config::get($this->workerName . '.ping_interval');
     if ((int) $ping_interval > 0) {
         $this->pingInterval = (int) $ping_interval;
     }
     // 获取心跳包数据
     $ping_data_or_path = \Man\Core\Lib\Config::get($this->workerName . '.ping_data');
     if (is_file($ping_data_or_path)) {
         $this->pingData = file_get_contents($ping_data_or_path);
     } else {
         $this->pingData = $ping_data_or_path;
     }
     // 不返回心跳回应(客户端发来的任何数据都算是回应)的限定值
     $this->pingNotResponseLimit = (int) \Man\Core\Lib\Config::get($this->workerName . '.ping_not_response_limit');
     // 设置定时任务,发送心跳
     if ($this->pingInterval > 0) {
         \Man\Core\Lib\Task::init($this->event);
         \Man\Core\Lib\Task::add($this->pingInterval, array($this, 'ping'));
     }
     // 主体循环,整个子进程会阻塞在这个函数上
     $ret = $this->event->loop();
     // 下面正常不会执行到
     $this->notice('worker loop exit');
     // 执行到就退出
     exit(0);
 }
예제 #8
0
 /**
  * 构造函数
  * @param int $port
  * @param string $ip
  * @param string $protocol
  * @return void
  */
 public function __construct($worker_name = null)
 {
     // worker name
     $this->workerName = $worker_name ? $worker_name : get_class($this);
     // 是否开启长连接
     $this->isPersistentConnection = (bool) Config::get($this->workerName . '.persistent_connection');
     // 最大请求数,超过这个数则安全重启,如果没有配置则使用PHP_INT_MAX
     $this->maxRequests = (int) Config::get($this->workerName . '.max_requests');
     $this->maxRequests = $this->maxRequests <= 0 ? PHP_INT_MAX : $this->maxRequests;
     // 预读数据长度,长连接需要设置此项
     $preread_length = (int) Config::get($this->workerName . '.preread_length');
     if ($preread_length > 0) {
         $this->prereadLength = $preread_length;
     } elseif (!$this->isPersistentConnection) {
         $this->prereadLength = 65535;
     }
     // 接收缓冲区大小限制
     if (($max_recv_buffer_size = Config::get($this->workerName . '.max_recv_buffer_size')) && $max_recv_buffer_size > 0) {
         $this->maxRecvBufferSize = $max_recv_buffer_size;
     }
     // 发送缓冲区大小限制
     if (($max_send_buffer_size = Config::get($this->workerName . '.max_send_buffer_size')) && $max_send_buffer_size > 0) {
         $this->maxSendBufferSize = $max_send_buffer_size;
     }
     // worker启动时间
     $this->statusInfo['start_time'] = time();
     //事件轮询库
     if (extension_loaded('libevent')) {
         $this->setEventLoopName('Libevent');
     }
     // 检查退出状态
     $this->addShutdownHook();
     // 初始化事件轮询库
     $this->event = new $this->eventLoopName();
     // 初始化任务系统
     Task::init($this->event);
     // 哪些目录或者文件不被监控
     if (Config::get('workerman.debug') && !Config::get($this->workerName . '.no_debug') && !Config::get($this->workerName . '.no_reload')) {
         // 保存排除监控的目录或者文件
         $this->monitorExcludePaths = $this->getExcludePaths();
         // 添加任务
         Task::add(1, array($this, 'checkFilesModify'));
     }
 }