feat(timer): 新增配置同步到数据库及主节点选举

T5: TimerServiceBase.syncConfigToDatabase() - syncs task config to DB
T6: HostServiceBase - auto master election, stale node detection,
    getMasterNode/setMasterNode methods
This commit is contained in:
augushong
2026-05-26 02:33:43 +08:00
parent d719a99d14
commit abeac2c3cb
5 changed files with 124 additions and 0 deletions

View File

@@ -75,6 +75,23 @@ class HostServiceBase
}
$host->save($data);
// 主节点自动选举:若无在线主节点,当前节点自动成为主节点
$master = SystemHost::where('is_master', 1)->where('status', 1)->find();
if (empty($master)) {
$host->is_master = 1;
$host->save();
Log::info("节点 [{$nodeId}] 自动当选为主节点。");
}
// 过期节点检测超过90秒无心跳的节点标记为离线
$staleTime = date('Y-m-d H:i:s', time() - 90);
$staleCount = SystemHost::where('status', 1)
->where('last_heartbeat_at', '<', $staleTime)
->update(['status' => 0]);
if ($staleCount > 0) {
Log::info("已将 {$staleCount} 个过期节点标记为离线。");
}
} catch (\Exception $e) {
throw $e;
Log::error("节点 [{$nodeId}] 心跳更新失败: " . $e->getMessage());
@@ -110,4 +127,38 @@ class HostServiceBase
'php_version' => PHP_VERSION,
];
}
/**
* 获取当前主节点的node_id.
*
* @return string|null 返回主节点ID无主节点时返回null
*/
public static function getMasterNode(): ?string
{
$master = SystemHost::where('is_master', 1)->where('status', 1)->find();
return $master ? $master->node_id : null;
}
/**
* 手动切换主节点.
*
* @param string $nodeId 目标节点的node_id
* @return bool 切换成功返回true节点不存在返回false
*/
public static function setMasterNode(string $nodeId): bool
{
// 先清除所有主节点标记
SystemHost::where('is_master', 1)->update(['is_master' => 0]);
// 设置新主节点
$host = SystemHost::where('node_id', $nodeId)->find();
if ($host) {
$host->is_master = 1;
$host->save();
return true;
}
return false;
}
}