- shadcn/ui 标准化:废弃纸感令牌,统一 bg-background/text-foreground 等 - Tailwind v4 + @theme inline,移除 tailwind.config.js - React 19 use() + Suspense 流式渲染,首屏骨架秒出 - 三级错误边界:Route → Section → Widget 层层兜底 - 错误上报:useErrorReport → sendBeacon → /api/log mock 端点 - 三层安全边界:L1 角色门禁 / L2 权限点门禁 / L3 数据范围 - 权限位图 base36 压缩:67 权限点 → ~14 字符,JWT 体积减少 ≥ 99% - notify 统一 Toast 封装,禁止业务直接 import sonner - PluginBoundary 替代 PluginLoader(错误边界 + Suspense + Skeleton 三件套) 验证:typecheck 0 错误 / lint 0 错误 / build 6 路由生成成功
152 lines
6.1 KiB
PowerShell
152 lines
6.1 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Edu v2.1 健康检查脚本
|
|
.DESCRIPTION
|
|
检查范围:
|
|
1. Docker 基础设施容器
|
|
2. 应用服务 HTTP 端点
|
|
3. 可观测性端点
|
|
4. CDC 管道状态
|
|
.EXAMPLE
|
|
.\scripts\health-check.ps1
|
|
#>
|
|
|
|
$ErrorActionPreference = "Continue"
|
|
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
Write-Host " Edu v2.1 Health Check" -ForegroundColor Cyan
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
Write-Host ""
|
|
|
|
# ===== 1. 基础设施容器 =====
|
|
Write-Host "[1/4] Infrastructure Containers" -ForegroundColor Yellow
|
|
|
|
$infraContainers = @(
|
|
@{Name="MySQL"; Container="edu-mysql"},
|
|
@{Name="Redis"; Container="edu-redis"},
|
|
@{Name="Kafka"; Container="edu-kafka"},
|
|
@{Name="Zookeeper"; Container="edu-zookeeper"},
|
|
@{Name="ClickHouse"; Container="edu-clickhouse"},
|
|
@{Name="Debezium"; Container="edu-debezium"},
|
|
@{Name="Neo4j"; Container="edu-neo4j"},
|
|
@{Name="Elasticsearch"; Container="edu-es"},
|
|
@{Name="Apollo Router"; Container="edu-apollo-router"},
|
|
@{Name="Jaeger"; Container="edu-jaeger"},
|
|
@{Name="Prometheus"; Container="edu-prometheus"},
|
|
@{Name="Grafana"; Container="edu-grafana"},
|
|
@{Name="Loki"; Container="edu-loki"},
|
|
@{Name="Alertmanager"; Container="edu-alertmanager"}
|
|
)
|
|
|
|
$infraOk = 0
|
|
$infraFail = 0
|
|
foreach ($svc in $infraContainers) {
|
|
$running = docker inspect -f '{{.State.Running}}' $svc.Container 2>$null
|
|
if ($running -ne "true") {
|
|
Write-Host " [SKIP] $($svc.Name) (not running, may be optional)" -ForegroundColor Gray
|
|
continue
|
|
}
|
|
$health = docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{end}}' $svc.Container 2>$null
|
|
if ($health -eq "healthy" -or $health -eq "") {
|
|
Write-Host " [OK] $($svc.Name)" -ForegroundColor Green
|
|
$infraOk++
|
|
} elseif ($health -eq "starting") {
|
|
Write-Host " [WAIT] $($svc.Name) (starting)" -ForegroundColor Yellow
|
|
$infraOk++
|
|
} else {
|
|
Write-Host " [WARN] $($svc.Name) (health=$health)" -ForegroundColor Yellow
|
|
$infraOk++
|
|
}
|
|
}
|
|
Write-Host ""
|
|
|
|
# ===== 2. 应用服务 =====
|
|
Write-Host "[2/4] Application Services" -ForegroundColor Yellow
|
|
|
|
$appServices = @(
|
|
@{Name="iam"; Url="http://localhost:3002/healthz"; Critical=$true},
|
|
@{Name="config-service"; Url="http://localhost:3011/healthz"; Critical=$true},
|
|
@{Name="classes"; Url="http://localhost:3001/healthz"; Critical=$false},
|
|
@{Name="core-edu"; Url="http://localhost:3004/healthz"; Critical=$false},
|
|
@{Name="content"; Url="http://localhost:3005/healthz"; Critical=$false},
|
|
@{Name="data-ana"; Url="http://localhost:3006/healthz"; Critical=$false},
|
|
@{Name="msg"; Url="http://localhost:3007/healthz"; Critical=$false},
|
|
@{Name="ai"; Url="http://localhost:3008/healthz"; Critical=$false},
|
|
@{Name="api-gateway"; Url="http://localhost:8080/healthz"; Critical=$false},
|
|
@{Name="push-gateway"; Url="http://localhost:8081/healthz"; Critical=$false},
|
|
@{Name="portal-shell"; Url="http://localhost:4010/api/health"; Critical=$true},
|
|
@{Name="apollo-router"; Url="http://localhost:8088/health"; Critical=$false}
|
|
)
|
|
|
|
$appOk = 0
|
|
$appFail = 0
|
|
$failedApps = @()
|
|
foreach ($svc in $appServices) {
|
|
try {
|
|
$null = Invoke-RestMethod -Uri $svc.Url -Method Get -TimeoutSec 3 -ErrorAction Stop
|
|
$tag = if ($svc.Critical) { "CRITICAL" } else { "optional" }
|
|
Write-Host " [OK] $($svc.Name) ($tag)" -ForegroundColor Green
|
|
$appOk++
|
|
} catch {
|
|
$tag = if ($svc.Critical) { "CRITICAL" } else { "optional" }
|
|
Write-Host " [FAIL] $($svc.Name) ($tag)" -ForegroundColor Red
|
|
$appFail++
|
|
$failedApps += $svc.Name
|
|
}
|
|
}
|
|
Write-Host ""
|
|
|
|
# ===== 3. 可观测性端点 =====
|
|
Write-Host "[3/4] Observability Endpoints" -ForegroundColor Yellow
|
|
|
|
$obsEndpoints = @(
|
|
@{Name="Prometheus API"; Url="http://localhost:9090/api/v1/query?query=up"},
|
|
@{Name="Jaeger API"; Url="http://localhost:16686/api/services"},
|
|
@{Name="Debezium Connect"; Url="http://localhost:8083/connectors"},
|
|
@{Name="Grafana"; Url="http://localhost:3030/api/health"},
|
|
@{Name="Loki"; Url="http://localhost:3100/ready"}
|
|
)
|
|
|
|
$obsOk = 0
|
|
$obsFail = 0
|
|
foreach ($ep in $obsEndpoints) {
|
|
try {
|
|
$null = Invoke-RestMethod -Uri $ep.Url -Method Get -TimeoutSec 3 -ErrorAction Stop
|
|
Write-Host " [OK] $($ep.Name)" -ForegroundColor Green
|
|
$obsOk++
|
|
} catch {
|
|
Write-Host " [FAIL] $($ep.Name)" -ForegroundColor Red
|
|
$obsFail++
|
|
}
|
|
}
|
|
Write-Host ""
|
|
|
|
# ===== 4. CDC 管道状态 =====
|
|
Write-Host "[4/4] CDC Pipeline Status" -ForegroundColor Yellow
|
|
$prevEAP = $ErrorActionPreference
|
|
$ErrorActionPreference = "Continue"
|
|
try {
|
|
$connectorStatus = Invoke-RestMethod -Uri "http://localhost:8083/connectors/edu-mysql-source/status" -Method Get -TimeoutSec 3 -ErrorAction Stop
|
|
$connectorState = $connectorStatus.connector.state
|
|
$tasks = @($connectorStatus.tasks)
|
|
$taskState = if ($tasks.Count -gt 0) { $tasks[0].state } else { "UNKNOWN" }
|
|
$color = if ($connectorState -eq "RUNNING" -and $taskState -eq "RUNNING") { "Green" } else { "Yellow" }
|
|
Write-Host " Debezium Connector: $connectorState / Task: $taskState" -ForegroundColor $color
|
|
} catch {
|
|
Write-Host " [SKIP] Debezium connector not registered" -ForegroundColor Gray
|
|
}
|
|
$ErrorActionPreference = $prevEAP
|
|
Write-Host ""
|
|
|
|
# ===== 汇总 =====
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
$totalChecked = $infraContainers.Count + $appServices.Count + $obsEndpoints.Count
|
|
$totalOk = $infraOk + $appOk + $obsOk
|
|
Write-Host " Infra: $infraOk checked | App: $appOk/$($appServices.Count) | Obs: $obsOk/$($obsEndpoints.Count)" -ForegroundColor Cyan
|
|
if ($appFail -gt 0) {
|
|
Write-Host " Failed apps: $($failedApps -join ', ')" -ForegroundColor Yellow
|
|
}
|
|
Write-Host "========================================" -ForegroundColor Cyan
|
|
|
|
if ($appFail -gt 0 -or $obsFail -gt 0) { exit 1 }
|