getMessage()); } return $newNodeId; } /** * 节点注册与心跳更新 * 这是一个原子操作,如果节点不存在则创建,如果存在则更新。 */ public static function heartbeat() { $nodeId = static::getNodeId(); if (empty($nodeId)) { Log::error('无法获取当前节点ID,心跳更新失败'); return; } try { $host = SystemHost::where('node_id', $nodeId)->find(); $data = static::collectHostInfo(); if (empty($host)) { $host = new SystemHost(); // 首次注册 $data['node_id'] = $nodeId; Log::info("节点 [{$nodeId}] 已成功注册并上线。"); } $host->save($data); } catch (\Exception $e) { throw $e; Log::error("节点 [{$nodeId}] 心跳更新失败: " . $e->getMessage()); Log::error($e); } } /** * 收集主机的性能指标和静态信息 (不依赖任何外部系统命令). * @return array */ public static function collectHostInfo(): array { // 获取CPU平均负载 (如果函数存在且未被禁用) $cpuLoad = null; if (function_exists('sys_getloadavg')) { $load = sys_getloadavg(); $cpuLoad = is_array($load) ? implode(',', array_map(fn ($l) => round($l, 2), $load)) : null; } return [ // 动态指标 'status' => 1, 'last_heartbeat_at' => date('Y-m-d H:i:s'), 'ip_address' => gethostbyname(gethostname()), 'cpu_load' => $cpuLoad, 'memory_usage' => memory_get_usage(), // false: 获取脚本自身内存占用 'disk_free' => disk_free_space(App::getRootPath()), 'disk_total' => disk_total_space(App::getRootPath()), // 静态信息 'os_info' => php_uname(), 'php_version' => PHP_VERSION, ]; } }