# 业务API压测脚本 - 风七六本地生活服务平台 # 包含真实业务场景的性能测试 param( [string]$BaseUrl = "http://localhost:8080", [int]$ConcurrentUsers = 50, [int]$DurationSeconds = 60 ) $ErrorActionPreference = "Stop" # 从环境变量获取测试凭证 $testUsername = $env:TEST_USERNAME $testPassword = $env:TEST_PASSWORD if (-not $testUsername) { $testUsername = "test" } if (-not $testPassword) { Write-Host "警告: TEST_PASSWORD 环境变量未设置,登录测试将使用默认值" -ForegroundColor Yellow $testPassword = "test123" } # 测试场景配置 $testScenarios = @( @{ Name = "用户登录" Method = "POST" Path = "/api/auth/login" Body = @{ username = $testUsername; password = $testPassword } | ConvertTo-Json Weight = 20 }, @{ Name = "获取用户信息" Method = "GET" Path = "/api/user/profile" Weight = 30 }, @{ Name = "查询商品列表" Method = "GET" Path = "/api/product/list?category=1" Weight = 25 }, @{ Name = "创建订单" Method = "POST" Path = "/api/order/create" Body = @{ productId = 1; quantity = 2 } | ConvertTo-Json Weight = 15 }, @{ Name = "健康检查" Method = "GET" Path = "/actuator/health" Weight = 10 } ) # 统计变量 $results = @{ TotalRequests = 0 SuccessRequests = 0 FailedRequests = 0 ResponseTimes = @() StartTime = $null EndTime = $null } Write-Host "========================================" -ForegroundColor Cyan Write-Host "风七六本地生活服务平台 - 业务API压测" -ForegroundColor Cyan Write-Host "========================================" -ForegroundColor Cyan Write-Host "基础URL: $BaseUrl" Write-Host "并发用户数: $ConcurrentUsers" Write-Host "测试时长: $DurationSeconds 秒" Write-Host "========================================" -ForegroundColor Cyan # 预热阶段 Write-Host "`n[预热阶段] 进行预热请求..." -ForegroundColor Yellow for ($i = 0; $i -lt 10; $i++) { try { $scenario = $testScenarios[0] $url = "$BaseUrl$($scenario.Path)" $headers = @{"Content-Type" = "application/json"} if ($scenario.Method -eq "POST") { $null = Invoke-WebRequest -Uri $url -Method $scenario.Method -Body $scenario.Body -Headers $headers -UseBasicParsing -TimeoutSec 10 } else { $null = Invoke-WebRequest -Uri $url -Method $scenario.Method -Headers $headers -UseBasicParsing -TimeoutSec 10 } } catch { Write-Host "预热请求失败: $_" -ForegroundColor Red } } Write-Host "预热完成! 开始压测...`n" -ForegroundColor Green # 压测主逻辑 $results.StartTime = Get-Date $jobs = @() # 创建并发任务 for ($user = 0; $user -lt $ConcurrentUsers; $user++) { $jobs += Start-Job -ScriptBlock { param($BaseUrl, $TestScenarios, $DurationSeconds) $endTime = (Get-Date).AddSeconds($DurationSeconds) $localResults = @{ Requests = 0 Success = 0 Failed = 0 ResponseTimes = @() } while ((Get-Date) -lt $endTime) { # 根据权重选择场景 $totalWeight = ($TestScenarios | Measure-Object -Property Weight -Sum).Sum $random = Get-Random -Minimum 0 -Maximum $totalWeight $currentWeight = 0 $selectedScenario = $null foreach ($s in $TestScenarios) { $currentWeight += $s.Weight if ($random -lt $currentWeight) { $selectedScenario = $s break } } if ($null -ne $selectedScenario) { $url = "$BaseUrl$($selectedScenario.Path)" $headers = @{"Content-Type" = "application/json"} try { $sw = [System.Diagnostics.Stopwatch]::StartNew() if ($selectedScenario.Method -eq "POST") { $null = Invoke-WebRequest -Uri $url -Method $selectedScenario.Method -Body $selectedScenario.Body -Headers $headers -UseBasicParsing -TimeoutSec 10 } else { $null = Invoke-WebRequest -Uri $url -Method $selectedScenario.Method -Headers $headers -UseBasicParsing -TimeoutSec 10 } $sw.Stop() $localResults.Requests++ $localResults.Success++ $localResults.ResponseTimes += $sw.Elapsed.TotalMilliseconds } catch { $localResults.Requests++ $localResults.Failed++ } } } return $localResults } -ArgumentList $BaseUrl, $testScenarios, $DurationSeconds } Write-Host "[压测中] 等待所有并发任务完成..." -ForegroundColor Yellow $jobs | Wait-Job | Out-Null $results.EndTime = Get-Date # 收集结果 Write-Host "`n[结果收集] 正在收集测试结果..." -ForegroundColor Yellow foreach ($job in $jobs) { $jobResult = Receive-Job -Job $job $results.TotalRequests += $jobResult.Requests $results.SuccessRequests += $jobResult.Success $results.FailedRequests += $jobResult.Failed $results.ResponseTimes += $jobResult.ResponseTimes Remove-Job -Job $job } # 计算统计数据 $totalTime = ($results.EndTime - $results.StartTime).TotalSeconds $avgResponseTime = if ($results.ResponseTimes.Count -gt 0) { ($results.ResponseTimes | Measure-Object -Average).Average } else { 0 } $p50ResponseTime = if ($results.ResponseTimes.Count -gt 0) { ($results.ResponseTimes | Sort-Object)[[Math]::Floor($results.ResponseTimes.Count * 0.5)] } else { 0 } $p95ResponseTime = if ($results.ResponseTimes.Count -gt 0) { ($results.ResponseTimes | Sort-Object)[[Math]::Floor($results.ResponseTimes.Count * 0.95)] } else { 0 } $p99ResponseTime = if ($results.ResponseTimes.Count -gt 0) { ($results.ResponseTimes | Sort-Object)[[Math]::Floor($results.ResponseTimes.Count * 0.99)] } else { 0 } $successRate = if ($results.TotalRequests -gt 0) { ($results.SuccessRequests / $results.TotalRequests) * 100 } else { 0 } $rps = if ($totalTime -gt 0) { $results.TotalRequests / $totalTime } else { 0 } # 生成报告 $report = @" ======================================== 风七六本地生活服务平台 - 业务API压测报告 ======================================== 测试时间: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss") 基础URL: $BaseUrl 并发用户数: $ConcurrentUsers 测试时长: $([Math]::Round($totalTime, 2)) 秒 --- 性能指标 --- 总请求数: $($results.TotalRequests) 成功请求: $($results.SuccessRequests) 失败请求: $($results.FailedRequests) 成功率: $([Math]::Round($successRate, 2))% 吞吐量: $([Math]::Round($rps, 2)) req/s --- 响应时间 (ms) --- 平均响应时间: $([Math]::Round($avgResponseTime, 2)) P50 响应时间: $([Math]::Round($p50ResponseTime, 2)) P95 响应时间: $([Math]::Round($p95ResponseTime, 2)) P99 响应时间: $([Math]::Round($p99ResponseTime, 2)) --- 测试场景 --- "@ foreach ($scenario in $testScenarios) { $report += " - $($scenario.Name) (权重: $($scenario.Weight)%)`n" } $report += @" ======================================== "@ Write-Host $report Write-Host "`n压测完成!" -ForegroundColor Green # 保存报告 $reportPath = "d:\FzxBDSH\FzxFile\业务API压测报告_$(Get-Date -Format 'yyyyMMdd_HHmmss').md" $report | Out-File -FilePath $reportPath -Encoding UTF8 Write-Host "报告已保存至: $reportPath" -ForegroundColor Cyan return $reportPath