Skip to content

Instantly share code, notes, and snippets.

@DrayChou
Created April 5, 2025 17:25
Show Gist options
  • Save DrayChou/42984304f46f6c4df9e838e32dbac36d to your computer and use it in GitHub Desktop.
Save DrayChou/42984304f46f6c4df9e838e32dbac36d to your computer and use it in GitHub Desktop.
windows 下简单的管理 sse 服务的脚本
# --- 配置 ---
# 定义要启动和监控的服务
# 格式: '服务名称' = '要执行的命令'
# 服务名称将用作后台作业的名称,便于识别和管理
$servicesToMonitor = @{
"SuperGateway_MCP_Time" = 'npx -y supergateway --stdio "uvx mcp-server-time --local-timezone=Asia/Shanghai" --port 34802'
"SuperGateway_MCP_Fetch" = 'npx -y supergateway --stdio "uvx mcp-server-fetch" --port 34815' # 注意: 你原始命令是 -port,这里保持一致,但通常应该是 --port
"SuperGateway_MCP_Memory" = 'npx -y supergateway --stdio "npx -y @modelcontextprotocol/server-memory" --port 34813'
}
# 检查间隔(秒)
$checkIntervalSeconds = 15
# --- 脚本主体 ---
# 清理之前可能存在的同名作业(可选,用于干净启动)
Write-Host "清理旧的监控作业..."
foreach ($serviceName in $servicesToMonitor.Keys) {
# 更健壮的任务清理方式
$job = Get-Job -Name $serviceName -ErrorAction SilentlyContinue
if ($job) {
try {
Stop-Job -Job $job -ErrorAction SilentlyContinue
Remove-Job -Job $job -ErrorAction SilentlyContinue
} catch {
Write-Warning "清理旧作业 $serviceName 时出现问题: $($_.Exception.Message)"
}
}
}
Write-Host "开始启动服务..."
# 初始启动所有服务
foreach ($serviceName in $servicesToMonitor.Keys) {
$command = $servicesToMonitor[$serviceName]
Write-Host "[$([DateTime]::Now)] 正在启动服务: $serviceName"
try {
# 使用 Start-Job 在后台运行命令
Start-Job -Name $serviceName -ScriptBlock {
param($cmd)
Write-Output "Executing: $cmd" # 在作业输出中记录命令
# 使用 Invoke-Expression 执行命令字符串
# 注意:如果命令包含复杂的引号或特殊字符,可能需要调整
Invoke-Expression $cmd
} -ArgumentList $command -ErrorAction Stop
Write-Host "[$([DateTime]::Now)] 服务 $serviceName 的作业已创建。"
Start-Sleep -Seconds 2 # 短暂暂停,避免同时启动过多进程造成瞬时高负载
} catch {
Write-Error "[$([DateTime]::Now)] 启动服务 $serviceName 失败: $($_.Exception.Message)"
}
}
Write-Host "`n--- 服务初始启动完成,开始进入监控循环 ---`n"
# 无限循环监控
try {
while ($true) {
Write-Host "-----------------------------------------------------"
Write-Host "[$([DateTime]::Now)] 开始检查服务状态..."
foreach ($serviceName in $servicesToMonitor.Keys) {
$job = Get-Job -Name $serviceName -ErrorAction SilentlyContinue # 添加 SilentlyContinue 以防万一
if ($null -eq $job) {
Write-Warning "[$([DateTime]::Now)] 未找到服务 $serviceName 的作业,尝试重新启动..."
$command = $servicesToMonitor[$serviceName]
try {
Start-Job -Name $serviceName -ScriptBlock {
param($cmd)
Write-Output "Executing: $cmd"
Invoke-Expression $cmd
} -ArgumentList $command -ErrorAction Stop
Write-Host "[$([DateTime]::Now)] 服务 $serviceName 的作业已重新创建。"
} catch {
Write-Error "[$([DateTime]::Now)] 重新启动服务 $serviceName 失败: $($_.Exception.Message)"
}
} else {
# 作业存在,检查状态
$jobState = $job.State
Write-Host "[$([DateTime]::Now)] 服务 $serviceName 状态: $jobState"
# 检查是否处于非运行状态(失败、停止、完成都视为需要重启)
if ($jobState -ne 'Running' -and $jobState -ne 'Blocked') {
Write-Warning "[$([DateTime]::Now)] 服务 $serviceName 处于非预期状态 ($jobState),准备重新启动..."
# 改进的作业清理流程
if ($job) {
Write-Host "[$([DateTime]::Now)] 正在尝试停止旧的 $serviceName 作业 (ID: $($job.Id))..."
# 首先尝试获取作业的进程ID以确保后续能干净地清理
$processId = $null
try {
$processId = (Get-Job -Id $job.Id).ChildJobs[0].Process.Id
Write-Host "[$([DateTime]::Now)] 找到进程ID: $processId"
} catch {
Write-Warning "[$([DateTime]::Now)] 无法获取 $serviceName 的进程ID: $($_.Exception.Message)"
}
# 尝试停止作业,使用更强大的错误处理
try {
Stop-Job -Job $job -ErrorAction Stop
Write-Host "[$([DateTime]::Now)] 旧的 $serviceName 作业已停止。"
} catch {
Write-Warning "[$([DateTime]::Now)] 停止作业失败: $($_.Exception.Message)"
# 如果Stop-Job失败且有进程ID,尝试直接终止进程
if ($processId) {
try {
Stop-Process -Id $processId -Force -ErrorAction SilentlyContinue
Write-Host "[$([DateTime]::Now)] 已强制终止进程 $processId"
} catch {
Write-Warning "[$([DateTime]::Now)] 无法终止进程 ${processId}: $($_.Exception.Message)"
}
}
}
# 无论上面成功与否,都尝试移除作业
Start-Sleep -Milliseconds 500 # 给进程一些时间完全终止
try {
# 使用 ErrorAction SilentlyContinue 避免因错误中断执行
Remove-Job -Job $job -Force -ErrorAction SilentlyContinue
Write-Host "[$([DateTime]::Now)] 已移除旧的 $serviceName 作业。"
} catch {
Write-Warning "[$([DateTime]::Now)] 移除作业失败,将继续尝试创建新作业: $($_.Exception.Message)"
}
}
# 稍作等待后重启
Start-Sleep -Seconds 2
$command = $servicesToMonitor[$serviceName]
Write-Host "[$([DateTime]::Now)] 正在重新启动服务: $serviceName"
try {
Start-Job -Name $serviceName -ScriptBlock {
param($cmd)
Write-Output "Executing: $cmd"
Invoke-Expression $cmd
} -ArgumentList $command -ErrorAction Stop
Write-Host "[$([DateTime]::Now)] 服务 $serviceName 的作业已重新创建。"
} catch {
Write-Error "[$([DateTime]::Now)] 重新启动服务 $serviceName 失败: $($_.Exception.Message)"
}
}
}
Start-Sleep -Milliseconds 500 # 在检查每个服务之间短暂暂停
}
Write-Host "[$([DateTime]::Now)] 本轮检查完成,将在 $checkIntervalSeconds 秒后进行下一轮检查。"
Write-Host "-----------------------------------------------------`n"
Start-Sleep -Seconds $checkIntervalSeconds
}
} finally {
# 脚本退出时的清理
Write-Host "脚本正在停止,清理所有监控作业..."
foreach ($serviceName in $servicesToMonitor.Keys) {
$job = Get-Job -Name $serviceName -ErrorAction SilentlyContinue
if ($job) {
Stop-Job -Job $job -Force -ErrorAction SilentlyContinue
Remove-Job -Job $job -Force -ErrorAction SilentlyContinue
Write-Host "已清理服务 $serviceName 的作业"
}
}
Write-Host "所有监控作业已清理。"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment