# 风七六平台自动化性能测试框架 # 用途: 自动化性能基准测试 + 性能回归检测 param( [ValidateSet("baseline", "quick", "full")] [string]$TestType = "quick", [string]$OutputDir = "FzxFile/performance_results", [switch]$CompareWithBaseline ) $ErrorActionPreference = "Continue" # 配置 $BASELINE_FILE = Join-Path $OutputDir "baseline_$(Get-Date -Format 'yyyy-MM-dd').json" $LAST_BENCHMARK_FILE = Join-Path $OutputDir "last_benchmark.json" # 创建输出目录 if (-not (Test-Path $OutputDir)) { New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null } Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan Write-Host "║ 风七六平台自动化性能测试框架 ║" -ForegroundColor Cyan Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan Write-Host "测试类型: $TestType" -ForegroundColor Yellow Write-Host "" # 服务列表 $services = @( @{ Name = "API Gateway"; Port = 8080; Endpoints = @("/actuator/health") }, @{ Name = "User Service"; Port = 8081; Endpoints = @("/actuator/health") }, @{ Name = "Auth Service"; Port = 8082; Endpoints = @("/actuator/health") }, @{ Name = "Merchant Service"; Port = 8083; Endpoints = @("/actuator/health") }, @{ Name = "Order Service"; Port = 8084; Endpoints = @("/actuator/health") } ) # 健康检查函数 function Test-ServiceHealth { param([string]$name, [int]$port) try { $url = "http://localhost:$port/actuator/health" $response = Invoke-WebRequest -Uri $url -TimeoutSec 10 -UseBasicParsing $content = $response.Content | ConvertFrom-Json return @{ Success = $true; Status = $content.status; StatusCode = $response.StatusCode } } catch { return @{ Success = $false; Error = $_.Exception.Message } } } # 响应时间测试函数 function Measure-EndpointLatency { param([string]$url, [int]$iterations = 10) $latencies = @() $successCount = 0 for ($i = 0; $i -lt $iterations; $i++) { try { $sw = [System.Diagnostics.Stopwatch]::StartNew() $response = Invoke-WebRequest -Uri $url -TimeoutSec 30 -UseBasicParsing $sw.Stop() $latencyMs = $sw.Elapsed.TotalMilliseconds $latencies += $latencyMs $successCount++ Write-Progress -Activity "测试 $url" -Status "迭代 $($i+1)/$iterations" -PercentComplete (($i+1)/$iterations*100) } catch { Write-Host "迭代 $($i+1) 失败: $_" -ForegroundColor Red } } if ($latencies.Count -eq 0) { return $null } $sorted = $latencies | Sort-Object $p50 = $sorted[ [Math]::Floor($sorted.Count * 0.5) ] $p95 = $sorted[ [Math]::Floor($sorted.Count * 0.95) ] $p99 = $sorted[ [Math]::Floor($sorted.Count * 0.99) ] return @{ Min = ($latencies | Measure-Object -Minimum).Minimum Max = ($latencies | Measure-Object -Maximum).Maximum Avg = ($latencies | Measure-Object -Average).Average P50 = $p50 P95 = $p95 P99 = $p99 SuccessRate = [Math]::Round($successCount / $iterations * 100, 2) Samples = $latencies.Count } } # 容器资源使用统计 function Get-ContainerResourceUsage { $stats = @() $containers = podman ps --format "{{.Names}}" foreach ($name in $containers) { try { # 获取容器统计信息 $statJson = podman stats $name --no-stream --format json | ConvertFrom-Json $stats += @{ Name = $name CPU = if ($statJson.CPUPerc) { $statJson.CPUPerc } else { "N/A" } MemUsage = if ($statJson.MemUsage) { $statJson.MemUsage } else { "N/A" } MemPerc = if ($statJson.MemPerc) { $statJson.MemPerc } else { "N/A" } NetIO = if ($statJson.NetIO) { $statJson.NetIO } else { "N/A" } } } catch { Write-Host "获取容器 $name 统计失败: $_" -ForegroundColor Red } } return $stats } # 比较性能基准 function Compare-Performance { param($current, $baseline) $results = @() $regressions = @() foreach ($svc in $current.Services) { $baselineSvc = $baseline.Services | Where-Object { $_.Name -eq $svc.Name } if ($baselineSvc) { $p95Change = [Math]::Round((($svc.P95 - $baselineSvc.P95) / $baselineSvc.P95) * 100, 2) $result = @{ Service = $svc.Name BaselineP95 = $baselineSvc.P95 CurrentP95 = $svc.P95 ChangePercent = $p95Change IsRegression = $p95Change -gt 20 # 20% 以上视为性能回退 } $results += $result if ($result.IsRegression) { $regressions += $result } } } return @{ Results = $results HasRegression = $regressions.Count -gt 0 Regressions = $regressions } } Write-Host "步骤 1/4: 检查服务健康状态" -ForegroundColor Cyan Write-Host "────────────────────────────────" -ForegroundColor Gray $serviceResults = @() foreach ($svc in $services) { $health = Test-ServiceHealth -name $svc.Name -port $svc.Port $statusColor = if ($health.Success -and $health.Status -eq "UP") { "Green" } else { "Red" } Write-Host " $($svc.Name): " -NoNewline Write-Host "$(if ($health.Success) { $health.Status } else { "DOWN" })" -ForegroundColor $statusColor $serviceResults += @{ Name = $svc.Name Port = $svc.Port Healthy = $health.Success -and $health.Status -eq "UP" HealthCheck = $health } } Write-Host "" Write-Host "步骤 2/4: 执行性能基准测试" -ForegroundColor Cyan Write-Host "────────────────────────────────" -ForegroundColor Gray $performanceResults = @() $iterations = if ($TestType -eq "full") { 100 } elseif ($TestType -eq "baseline") { 50 } else { 20 } foreach ($svc in $serviceResults | Where-Object { $_.Healthy }) { Write-Host "" Write-Host "测试服务: $($svc.Name)" -ForegroundColor Yellow foreach ($endpoint in $svc.Endpoints) { $url = "http://localhost:$($svc.Port)$endpoint" Write-Host " 端点: $url, 迭代: $iterations" -ForegroundColor Gray $latencyResult = Measure-EndpointLatency -url $url -iterations $iterations if ($latencyResult) { Write-Host " 平均: $([Math]::Round($latencyResult.Avg, 2))ms, P95: $([Math]::Round($latencyResult.P95, 2))ms, 成功率: $($latencyResult.SuccessRate)%" -ForegroundColor Green $performanceResults += @{ Name = $svc.Name Endpoint = $endpoint Latency = $latencyResult } } else { Write-Host " 无法测试端点" -ForegroundColor Red } } } Write-Host "" Write-Host "步骤 3/4: 收集资源使用统计" -ForegroundColor Cyan Write-Host "────────────────────────────────" -ForegroundColor Gray $containerStats = Get-ContainerResourceUsage foreach ($stat in $containerStats | Select-Object -First 10) { Write-Host " $($stat.Name): CPU=$($stat.CPU), Mem=$($stat.MemUsage)" } Write-Host "" Write-Host "步骤 4/4: 保存并分析结果" -ForegroundColor Cyan Write-Host "────────────────────────────────" -ForegroundColor Gray # 构建完整结果对象 $fullResult = @{ Timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" TestType = $TestType Services = $performanceResults ContainerStats = $containerStats } # 保存结果 $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" $resultFile = Join-Path $OutputDir "performance_test_$timestamp.json" $fullResult | ConvertTo-Json -Depth 10 | Set-Content -Path $resultFile $fullResult | ConvertTo-Json -Depth 10 | Set-Content -Path $LAST_BENCHMARK_FILE Write-Host " 结果保存至: $resultFile" -ForegroundColor Green # 如果是基准测试,保存基准 if ($TestType -eq "baseline") { Copy-Item -Path $resultFile -Destination $BASELINE_FILE -Force Write-Host " 基准线已保存至: $BASELINE_FILE" -ForegroundColor Green } # 性能回归检测 if ($CompareWithBaseline -and (Test-Path $BASELINE_FILE)) { Write-Host "" Write-Host "比较性能基准..." -ForegroundColor Yellow $baseline = Get-Content $BASELINE_FILE | ConvertFrom-Json $comparison = Compare-Performance -current $fullResult -baseline $baseline if ($comparison.HasRegression) { Write-Host "" Write-Host "⚠️ 检测到性能回退!" -ForegroundColor Red Write-Host "" foreach ($reg in $comparison.Regressions) { Write-Host " $($reg.Service): P95 从 $($reg.BaselineP95)ms 升至 $($reg.CurrentP95)ms ($($reg.ChangePercent)%)" -ForegroundColor Red } exit 1 } else { Write-Host "" Write-Host "✅ 性能正常,无明显回退!" -ForegroundColor Green } } Write-Host "" Write-Host "╔══════════════════════════════════════════════════════════════╗" -ForegroundColor Green Write-Host "║ 性能测试完成! ║" -ForegroundColor Green Write-Host "╚══════════════════════════════════════════════════════════════╝" -ForegroundColor Green Write-Host "" Write-Host "快速查看结果:" -ForegroundColor Yellow Write-Host " 测试报告: $resultFile" Write-Host " 查看所有结果: Get-ChildItem $OutputDir" Write-Host "" Write-Host "使用方法:" -ForegroundColor Gray Write-Host " 创建基准: .\automated_performance_test.ps1 -TestType baseline" Write-Host " 快速测试: .\automated_performance_test.ps1 -TestType quick" Write-Host " 完整测试: .\automated_performance_test.ps1 -TestType full" Write-Host " 对比基准: .\automated_performance_test.ps1 -CompareWithBaseline" Write-Host ""