getMessage()); } return $newHostId; } /** * 主机注册与心跳更新 * 这是一个原子操作,如果主机不存在则创建,如果存在则更新。 */ public static function heartbeat() { $hostId = self::getHostId(); if (empty($hostId)) { Log::error('无法获取当前主机ID,心跳更新失败'); return; } try { // findOrEmpty可以避免查询不到时抛出异常 $host = SystemHost::where('host_id', $hostId)->findOrEmpty(); // 收集动态性能指标 $data = self::collectHostMetrics(); if ($host->isEmpty()) { // 首次注册:补充一次性的静态信息 $data['host_id'] = $hostId; $data = array_merge($data, self::collectStaticInfo()); SystemHost::create($data); Log::info("主机 [{$hostId}] 已成功注册并上线。"); } else { // 后续心跳:仅更新动态信息 $host->save($data); } } catch (\Exception $e) { Log::error("主机 [{$hostId}] 心跳更新失败: " . $e->getMessage()); } } /** * 收集主机的动态性能指标 (不依赖任何外部系统命令). * @return array */ public static function collectHostMetrics(): 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()), ]; } /** * 收集主机的静态信息 (仅在首次注册时调用). * @return array */ public static function collectStaticInfo(): array { return [ 'os_info' => php_uname(), 'php_version' => PHP_VERSION, ]; } }