import http from 'k6/http'; import { check, sleep } from 'k6'; import { Rate, Trend } from 'k6/metrics'; const errorRate = new Rate('errors'); const responseTime = new Trend('response_time'); export const options = { stages: [ { duration: '1m', target: 50 }, // 1分钟内增加到50用户 { duration: '2m', target: 100 }, // 2分钟内增加到100用户 { duration: '3m', target: 200 }, // 3分钟内增加到200用户 { duration: '5m', target: 300 }, // 5分钟内增加到300用户(压力峰值) { duration: '2m', target: 100 }, // 2分钟内减少到100用户 { duration: '1m', target: 0 }, // 1分钟内减少到0 ], thresholds: { // 压力测试允许比负载测试更高的延迟;峰值 300 并发下 p95<2s、p99<3s 视为可接受 http_req_duration: ['p(95)<2000', 'p(99)<3000'], http_req_failed: ['rate<0.05'], // 错误率<5% errors: ['rate<0.05'], }, }; const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000'; export default function () { // 80% 访问首页、20% 访问关于页面 // 注:/api/contact 依赖外部邮件服务并存在 IP 限流,/api/health 未实现, // 因此本脚本仅验证本地营销页面的承载能力。 const rand = Math.random(); let res; if (rand < 0.8) { res = http.get(`${BASE_URL}/`, { tags: { name: 'home' }, }); } else { res = http.get(`${BASE_URL}/about`, { tags: { name: 'about' }, }); } const success = check(res, { 'status is 200': (r) => r.status === 200, 'response time < 2000ms': (r) => r.timings.duration < 2000, }); errorRate.add(!success); responseTime.add(res.timings.duration); sleep(Math.random() * 2 + 0.5); // 0.5-2.5秒随机等待 } export function handleSummary(data) { return { 'performance/stress-test-summary.json': JSON.stringify(data, null, 2), }; }