diff --git a/src/Monitor/Main.php b/src/Monitor/Main.php index e3fc2c3..9d79f2c 100644 --- a/src/Monitor/Main.php +++ b/src/Monitor/Main.php @@ -18,16 +18,18 @@ class Main { public $logger = null; public $pid = null; //进程ID - public $masterPidFile = ''; + public $masterPidFile = ''; //主进程id存储文件路径 + public $errorInfoFile = ''; //错误文件路径 private $config = []; private $workers = []; //子进程列表 + private $memoryTable = null; //内存表 /** * 初始化. * * @param array $config 配置项 * [ - 'tickerTime' => 5;//每5秒循环一次 + 'tickerTime' => 5;//每5秒循环一次 * ] */ public function __construct($config) @@ -37,6 +39,7 @@ public function __construct($config) \swoole_process::daemon(); if (isset($this->config['pidPath']) && !empty($this->config['pidPath'])) { $this->masterPidFile = $this->config['pidPath'] . '/master.pid'; + $this->errorInfoFile = $this->config['pidPath'] . '/errorInfo'; } else { echo 'config pidPath must be set!' . PHP_EOL; exit; @@ -75,20 +78,22 @@ public function addTimeListener() throw new \Exception(Errors::SETTING_ERROR_MESSAGE, Errors::SETTING_ERROR_CODE); } //内存方式记录出错次数 - $swooleTable = new MemoryTable(count($this->config['linkList'])); + $this->swooleTable = new MemoryTable(count($this->config['linkList'])); + //载入出错数据 + $this->getErrorInfo(); try { - $factoryLink = new FactoryLink(); - $factoryLink->getConfig($this->config); - $factoryNotice = new FactoryNotice(); - $factoryNotice->getConfig($this->config); - \swoole_timer_tick($this->config['tickerTime'] * 1000, function () use ($factoryLink, $factoryNotice, $swooleTable) { + \swoole_timer_tick($this->config['tickerTime'] * 1000, function () { + $this->workers = []; + $factoryLink = new FactoryLink(); + $factoryLink->getConfig($this->config); + $factoryNotice = new FactoryNotice(); + $factoryNotice->getConfig($this->config); $customMsgKey = 1; $mod = 2 | \swoole_process::IPC_NOWAIT; //这里设置消息队列为非阻塞模式 - $workers = []; for ($i=0; $i < $this->config['workerNum']; $i++) { //开启子进程检查链路 - $process = new \swoole_process(function ($worker) use ($factoryLink, $factoryNotice, $swooleTable) { + $process = new \swoole_process(function ($worker) use ($factoryLink, $factoryNotice) { $this->setProcessName(false); $pid = $worker->pid; $this->logger->log('Worker Start, PID=' . $pid); @@ -96,7 +101,7 @@ public function addTimeListener() while ($recv = $worker->pop()) { //获取队列内容 获取 链路对象 list($linkSetting, $workerIndex) = @json_decode($recv, true); - $linkObject = $factoryLink->getLinkObject($linkSetting, $swooleTable); + $linkObject = $factoryLink->getLinkObject($linkSetting, $this->swooleTable); if ($linkObject) { $sendNotice = false; //默认不告警 if (!isset($linkSetting['checkList'])) { @@ -122,10 +127,12 @@ public function addTimeListener() $noticeObject = $factoryNotice->getNoticeObject($linkSetting); $noticeObject->setContent($linkObject->noticeMsg); $noticeObject->send(); + unset($noticeObject); } } else { $this->logger->errorLog('get link object failed,linkSetting:' . json_encode($linkSetting)); } + unset($linkObject); } // if (false !== $workerIndex) { // unset($this->workers[$workerIndex]); @@ -136,6 +143,7 @@ public function addTimeListener() $pid = $process->start(); $this->workers[] = [$pid, $process]; } + //循环取模入队 $this->config['linkList'] = array_values($this->config['linkList']); $countWorkers = count($this->workers); @@ -151,10 +159,15 @@ public function addTimeListener() foreach ($this->workers as $worker) { @\swoole_process::wait(); } + + //回收内存 + $factoryLink = null; + $factoryNotice = null; + unset($factoryLink, $factoryNotice); }); } catch (\Exception $ex) { //报错删除分配内存 - $swooleTable->flushAll(); + $this->swooleTable->flushAll(); Utils::catchError($this->logger, $ex); } } @@ -199,6 +212,7 @@ public function forceExitService() { $this->forceExitWorkers(); $this->forceExistMaster(); + $this->writeErrorInfo(); //写入错误信息 $stopStatus = !file_exists($this->masterPidFile) ? 'success' : 'failed'; echo "\rlink-monitor service stop " . $stopStatus . ' ' . PHP_EOL; $this->logger->systemLog('stop link-monitor service ' . $stopStatus); @@ -242,4 +256,30 @@ public function showStatusInfo() { echo "\rlink-monitor service status:" . (file_exists($this->masterPidFile) ? ('active, Master pid:' . file_get_contents($this->masterPidFile)) : 'inactive') . PHP_EOL; } + + /** + * 重启将出错信息写入文件. + */ + public function writeErrorInfo() + { + $memoryList = $this->swooleTable->getKeysValues(); + @file_put_contents($this->errorInfoFile, json_encode($memoryList)); + } + + /** + * 启动获取出错信息. + */ + public function getErrorInfo() + { + //读取文件 + $errorFile = @file_get_contents($this->errorInfoFile); + if ($errorFile) { + $errorInfo = @json_decode($errorFile, true); + if ($errorInfo) { + foreach ($errorInfo as $key=>$value) { + $this->swooleTable->setKeyValues($key, $value); + } + } + } + } } diff --git a/src/Monitor/MemoryTable.php b/src/Monitor/MemoryTable.php index ea4b307..e0187b0 100644 --- a/src/Monitor/MemoryTable.php +++ b/src/Monitor/MemoryTable.php @@ -21,7 +21,7 @@ class MemoryTable ]; public static $staticTable = null; - public $table = null; + private $table = null; public function __construct($linkCount = 5) { @@ -113,4 +113,28 @@ public function flushAll() $this->table->del($key); } } + + /** + * 获取全部key与value. + */ + public function getKeysValues() + { + $ret = []; + foreach ($this->table as $key=>$row) { + $ret[$key] = $row; + } + + return $ret; + } + + /** + * 单个key设置所有值 + * + * @param string $linkKey 标记链路唯一key + * @param array $values 对应数据 + */ + public function setKeyValues($linkKey, $values) + { + $this->table->set($linkKey, $values); + } }