/** * 进程启动时初始化 * @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); }
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')); }
/** * 该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; }
/** * 该进程开始服务 * @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(); }
/** * 服务运行 * @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("[1A\n[KWorkerman start success ...[0m", true); // 标记服务状态为运行中 self::$serviceStatus = self::STATUS_RUNNING; // 初始化任务 \Man\Core\Lib\Task::init(); // 关闭标准输出 self::resetStdFd(); // 主循环 self::loop(); }
/** * 初始化 * 统计目录检查 * 初始化任务 * @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)); }
/** * 进程启动 */ 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); }
/** * 构造函数 * @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')); } }