192 lines
8.2 KiB
PowerShell
192 lines
8.2 KiB
PowerShell
<#
|
||
.SYNOPSIS
|
||
Edu start all application services script
|
||
.DESCRIPTION
|
||
Starts 10 application services + 1 frontend (teacher-portal)
|
||
Each service runs in a separate terminal window for log visibility
|
||
Automatically injects Python service env vars (CLICKHOUSE/KAFKA/OTEL)
|
||
Prerequisite: infrastructure containers (MySQL/Redis/Kafka/ClickHouse etc) must be running
|
||
.PARAMETER SkipInfraCheck
|
||
Skip infrastructure health check (use when infra is known to be running)
|
||
.EXAMPLE
|
||
.\scripts\start-all.ps1
|
||
.\scripts\start-all.ps1 -SkipInfraCheck
|
||
#>
|
||
param(
|
||
[switch]$SkipInfraCheck
|
||
)
|
||
|
||
$ErrorActionPreference = "Stop"
|
||
$ProjectRoot = Split-Path -Parent $PSScriptRoot
|
||
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host " Edu Start All Services" -ForegroundColor Cyan
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
|
||
# ===== 1. Infrastructure health check =====
|
||
if (-not $SkipInfraCheck) {
|
||
Write-Host "[1/4] Checking infrastructure health..." -ForegroundColor Yellow
|
||
$infraServices = @(
|
||
@{Name="MySQL"; Container="edu-mysql"},
|
||
@{Name="Redis"; Container="edu-redis"},
|
||
@{Name="Kafka"; Container="edu-kafka"},
|
||
@{Name="ClickHouse"; Container="edu-clickhouse"},
|
||
@{Name="Debezium"; Container="edu-debezium"},
|
||
@{Name="Jaeger"; Container="edu-jaeger"}
|
||
)
|
||
$allHealthy = $true
|
||
$prevEAP = $ErrorActionPreference
|
||
$ErrorActionPreference = "Continue"
|
||
foreach ($svc in $infraServices) {
|
||
$running = docker inspect -f '{{.State.Running}}' $svc.Container 2>$null
|
||
if ($running -ne "true") {
|
||
Write-Host " [FAIL] $($svc.Name) not running" -ForegroundColor Red
|
||
$allHealthy = $false
|
||
continue
|
||
}
|
||
# 条件模板:Health 不存在时返回空字符串,不报错
|
||
$health = docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{end}}' $svc.Container 2>$null
|
||
if ($health -eq "healthy") {
|
||
Write-Host " [OK] $($svc.Name) ($($svc.Container))" -ForegroundColor Green
|
||
} else {
|
||
Write-Host " [WARN] $($svc.Name) running (no healthcheck)" -ForegroundColor Yellow
|
||
}
|
||
}
|
||
$ErrorActionPreference = $prevEAP
|
||
if (-not $allHealthy) {
|
||
Write-Host ""
|
||
Write-Host "Infrastructure not ready. Start it first:" -ForegroundColor Red
|
||
Write-Host " docker compose -f infra/docker-compose.yml --profile p6 --profile observability up -d" -ForegroundColor White
|
||
exit 1
|
||
}
|
||
Write-Host ""
|
||
}
|
||
|
||
# ===== 2. Environment variables =====
|
||
Write-Host "[2/4] Preparing environment variables..." -ForegroundColor Yellow
|
||
|
||
$env:DEV_MODE = "true"
|
||
$env:OTEL_EXPORTER_OTLP_ENDPOINT = "http://localhost:4318"
|
||
$env:DATABASE_URL = "mysql://edu:changeme@localhost:3306/next_edu_cloud"
|
||
$env:REDIS_URL = "redis://localhost:6379"
|
||
$env:JWT_SECRET = "p1-dev-secret-change-in-production"
|
||
$env:KAFKA_BROKERS = "localhost:9092"
|
||
|
||
$pyEnv = @{
|
||
CLICKHOUSE_HOST = "localhost"
|
||
CLICKHOUSE_PORT = "8123"
|
||
CLICKHOUSE_USER = "default"
|
||
CLICKHOUSE_PASSWORD = "clickhouse"
|
||
CLICKHOUSE_DATABASE = "edu_analytics"
|
||
KAFKA_BROKERS = "localhost:9092"
|
||
OTEL_ENDPOINT = "http://localhost:4318"
|
||
DEV_MODE = "true"
|
||
}
|
||
|
||
Write-Host " DEV_MODE=true (dev-token bypass)" -ForegroundColor Green
|
||
Write-Host " OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318" -ForegroundColor Green
|
||
Write-Host ""
|
||
|
||
# ===== 3. Start application services =====
|
||
Write-Host "[3/4] Starting application services (11 windows)..." -ForegroundColor Yellow
|
||
|
||
$services = @(
|
||
@{Title="edu-app-classes"; Cmd="pnpm"; Args=@("--filter","@edu/classes-service","dev"); Dir="$ProjectRoot"},
|
||
@{Title="edu-app-iam"; Cmd="pnpm"; Args=@("--filter","@edu/iam-service","dev"); Dir="$ProjectRoot"},
|
||
@{Title="edu-app-teacher-bff"; Cmd="pnpm"; Args=@("--filter","@edu/teacher-bff","dev"); Dir="$ProjectRoot"},
|
||
@{Title="edu-app-core-edu"; Cmd="pnpm"; Args=@("--filter","@edu/core-edu-service","dev"); Dir="$ProjectRoot"},
|
||
@{Title="edu-app-content"; Cmd="pnpm"; Args=@("--filter","@edu/content-service","dev"); Dir="$ProjectRoot"},
|
||
@{Title="edu-app-msg"; Cmd="pnpm"; Args=@("--filter","@edu/msg-service","dev"); Dir="$ProjectRoot"},
|
||
@{Title="edu-app-data-ana"; Cmd="uv"; Args=@("run","uvicorn","data_ana.main:app","--host","0.0.0.0","--port","3006","--reload"); Dir="$ProjectRoot\services\data-ana"; PyEnv=$true},
|
||
@{Title="edu-app-ai"; Cmd="uv"; Args=@("run","uvicorn","ai.main:app","--host","0.0.0.0","--port","3008","--reload"); Dir="$ProjectRoot\services\ai"; PyEnv=$true},
|
||
@{Title="edu-app-api-gateway"; Cmd="go"; Args=@("run","."); Dir="$ProjectRoot\services\api-gateway"; GoEnv=$true},
|
||
@{Title="edu-app-push-gateway"; Cmd="go"; Args=@("run","."); Dir="$ProjectRoot\services\push-gateway";GoEnv=$true},
|
||
@{Title="edu-app-teacher-portal";Cmd="pnpm";Args=@("--filter","teacher-portal","dev"); Dir="$ProjectRoot"}
|
||
)
|
||
|
||
foreach ($svc in $services) {
|
||
$cmdStr = "$($svc.Cmd) $($svc.Args -join ' ')"
|
||
|
||
$psCmd = "Set-Location '$($svc.Dir)'; "
|
||
|
||
if ($svc.PyEnv) {
|
||
foreach ($kv in $pyEnv.GetEnumerator()) {
|
||
$psCmd += "`$env:$($kv.Key)='$($kv.Value)'; "
|
||
}
|
||
}
|
||
|
||
if ($svc.GoEnv) {
|
||
$psCmd += "`$env:Path = 'C:\Program Files\Go\bin;' + `$env:Path; "
|
||
}
|
||
|
||
$psCmd += "$cmdStr; Write-Host ''; Write-Host 'Service stopped. Press any key to close...' -ForegroundColor Yellow; `$null = `$Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')"
|
||
|
||
Start-Process -FilePath "powershell" -ArgumentList "-NoExit","-Command",$psCmd -WindowStyle Normal | Out-Null
|
||
|
||
Write-Host " [START] $($svc.Title)..." -ForegroundColor Green
|
||
Start-Sleep -Milliseconds 500
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host " All services started in new windows. Waiting 30s for init..." -ForegroundColor Yellow
|
||
Start-Sleep -Seconds 30
|
||
|
||
# ===== 4. Health check =====
|
||
Write-Host "[4/4] Health check..." -ForegroundColor Yellow
|
||
Write-Host ""
|
||
|
||
$healthServices = @(
|
||
@{Name="classes"; Url="http://localhost:3001/healthz"},
|
||
@{Name="iam"; Url="http://localhost:3002/healthz"},
|
||
@{Name="teacher-bff"; Url="http://localhost:3003/healthz"},
|
||
@{Name="core-edu"; Url="http://localhost:3004/healthz"},
|
||
@{Name="content"; Url="http://localhost:3005/healthz"},
|
||
@{Name="data-ana"; Url="http://localhost:3006/healthz"},
|
||
@{Name="msg"; Url="http://localhost:3007/healthz"},
|
||
@{Name="ai"; Url="http://localhost:3008/healthz"},
|
||
@{Name="api-gateway"; Url="http://localhost:8080/healthz"},
|
||
@{Name="push-gateway"; Url="http://localhost:8081/healthz"},
|
||
@{Name="teacher-portal";Url="http://localhost:3000/"}
|
||
)
|
||
|
||
$okCount = 0
|
||
$failCount = 0
|
||
foreach ($svc in $healthServices) {
|
||
$retries = 0
|
||
$maxRetries = 5
|
||
$success = $false
|
||
while ($retries -lt $maxRetries -and -not $success) {
|
||
try {
|
||
$null = Invoke-RestMethod -Uri $svc.Url -Method Get -TimeoutSec 3 -ErrorAction Stop
|
||
Write-Host " [OK] $($svc.Name)" -ForegroundColor Green
|
||
$success = $true
|
||
$okCount++
|
||
} catch {
|
||
$retries++
|
||
if ($retries -lt $maxRetries) {
|
||
Start-Sleep -Seconds 3
|
||
}
|
||
}
|
||
}
|
||
if (-not $success) {
|
||
Write-Host " [FAIL] $($svc.Name) (failed after $maxRetries retries)" -ForegroundColor Red
|
||
$failCount++
|
||
}
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host " Started: [OK] $okCount ready / [FAIL] $failCount failed" -ForegroundColor Cyan
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
Write-Host "Next steps:" -ForegroundColor Yellow
|
||
Write-Host " Health check: .\scripts\health-check.ps1" -ForegroundColor White
|
||
Write-Host " CDC test: .\scripts\test-cdc.ps1" -ForegroundColor White
|
||
Write-Host " Stop all: .\scripts\stop-all.ps1" -ForegroundColor White
|
||
Write-Host ""
|
||
|
||
if ($failCount -gt 0) {
|
||
exit 1
|
||
}
|