1. 引言

随着 Web 应用规模扩大,必须高效处理日益增长的用户并发量和请求。负载测试是评估应用在不同流量条件下性能的关键手段,能帮助识别潜在瓶颈并确保系统可靠性。

举个栗子:电商平台的闪购活动会引发用户激增。若未经充分负载测试,性能瓶颈可能导致响应缓慢甚至系统崩溃,直接影响用户体验和收入。

k6 是一款强大的开源负载测试工具,它将简洁性与高级性能分析完美结合。通过 JavaScript 脚本和高效执行能力,开发者可创建全面的性能测试场景。

本教程将完整覆盖:k6 环境搭建 → 负载测试执行 → 性能指标分析 → 最佳实践应用,确保系统性能最优化。

2. 负载测试环境搭建

要使用 k6 进行负载测试,需先安装工具并创建测试脚本。

2.1. 安装

使用系统包管理器即可快速安装 k6

$ brew install k6  # macOS 示例

验证安装是否成功:

$ k6 version

成功安装会显示版本信息:

k6 v0.56.0 (go1.23.4, darwin/arm64)

2.2. 测试脚本

创建基础测试脚本 test.js,展示 k6 核心功能:

import http from 'k6/http';
import { sleep, check } from 'k6';

// 测试配置
export const options = {
  vus: 10, // 模拟并发虚拟用户
  duration: '30s',
  
  thresholds: {
    http_req_duration: ['p(95)<500'], // 95% 请求需在 500ms 内完成
    http_req_failed: ['rate<0.01']    // 请求失败率 < 1%
  }
};

// 测试场景
export default function() {
  
  // 模拟请求
  const response = http.get('https://test-api.k6.io'); 
  
  // 验证响应
  check(response, {
    'status is 200': (r) => r.status === 200,
    'response time is acceptable': (r) => r.timings.duration < 500
  });
  
  // 模拟用户行为
  sleep(1);
}

此脚本配置了:

  • 10 个虚拟用户持续 30 秒
  • 性能阈值:95% 请求 <500ms,失败率 <1%
  • 测试场景:向 API 接口发送 GET 请求
  • 每个虚拟用户在请求间暂停 1 秒,保持真实负载

执行测试:

k6 run test.js

脚本将捕获关键性能指标,验证响应条件,并生成包含响应时间、请求速率和潜在故障的完整报告。

3. 执行负载测试

完成基础环境搭建后,我们开始探索更贴近真实应用的测试场景。

3.1. 高级测试场景

通过 options 对象灵活配置测试场景,模拟真实流量模式。例如使用 ramp-up/ramp-down 阶段模拟用户行为

export const options = {
  stages: [
    { duration: '1m', target: 20 }, // 1 分钟内爬升至 20 用户
    { duration: '3m', target: 20 }, // 稳定运行 3 分钟
    { duration: '1m', target: 0 },  // 1 分钟内降至 0 用户
  ],
};

这种配置逐步增加负载 → 保持稳定 → 平滑减少,能真实反映应用性能表现。

3.2. 多接口测试

在单个脚本中测试多个 API 路由,实现全面覆盖:

export default function() {
  
  // 模拟多样化用户交互
  const responses = http.batch([
    ['GET', 'https://test-api.k6.io/public/crocodiles/'],
    ['POST', 'https://test-api.k6.io/auth/basic/login/', JSON.stringify({username:'test_user',password:'secure123'})]
  ]);

  // 验证多接口响应
  check(responses[0], { 'Crocodiles loaded': (r) => r.status === 200 });
  check(responses[1], { 'Login done': (r) => r.status === 200 });
}

脚本通过批量请求(获取鳄鱼列表 + 登录)同步验证各接口返回 HTTP 200 状态码。

3.3. 内置指标

k6 自动提供丰富的性能指标

  • http_req_duration:请求总耗时(含 DNS、连接、响应时间)
  • http_reqs:HTTP 请求总数
  • http_req_failed:失败请求比例
  • vus:当前虚拟用户数
  • iterations:脚本迭代总次数

这些指标为性能分析提供全面基础数据。

3.4. 自定义指标

自定义指标是 k6 的强大功能,可监控特定性能维度。例如用计数器跟踪登录失败:

import { Counter } from 'k6/metrics';

let loginFailures = new Counter('login_failures');

export default function () {
  let res = http.post('https://test-api.k6.io/auth/basic/login/', { 
    username: 'test_user',
    password: 'wrong_password'
  });
  if (res.status !== 200) {
    loginFailures.add(1); // 登录失败时计数器+1
  }
}

k6 的可定制场景、多接口测试和精细指标追踪,为我们提供了全面评估应用性能的武器库。

4. 负载测试结果分析

分析测试结果是理解性能瓶颈、确保系统可靠性的关键环节。

4.1. 结果导出

k6 支持多种格式导出结果以便深度分析。例如导出为 JSON:

$ k6 run --out json=results.json test.js

便于将数据集成到 Grafana 等可视化工具或生成详细报告。

终端输出示例:

     execution: local
        script: test.js
        output: json (results.json)
     scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop):
              * default: 10 looping VUs for 30s (gracefulStop: 30s)
     ✓ status is 200
     ✓ response time is acceptable

   ✓ http_req_duration..............: avg=109.59ms min=104.52ms med=108.86ms max=190.22ms p(90)=113.03ms p(95)=114.66ms
   ✓ http_req_failed................: 0.00%   0 out of 270
     vus............................: 10      min=10         max=10
     vus_max........................: 10      min=10         max=10

running (0m30.3s), 00/10 VUs, 270 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs  30s

这些指标清晰展现系统性能,突出需优化的领域。

4.2. 结果分析

分析测试结果时,重点关注以下维度

响应时间分析

  • 监控 p95/p99 百分位,评估 95%/99% 请求的性能表现
  • 追踪最大响应时间,识别影响用户体验的异常值
  • 检测持续负载下的性能衰减模式

错误率分析

  • 关注请求失败比例,评估整体可靠性
  • 分析错误类型与模式(超时、4xx/5xx 响应等)
  • 观察系统接近性能极限时的行为表现

资源利用率分析

  • 监控 CPU 使用模式,发现过载或瓶颈
  • 关注高负载下的内存消耗
  • 追踪网络吞吐量,识别带宽或 API 容量限制

5. 最佳实践与常见陷阱

获取结果后,遵循最佳实践并避开陷阱至关重要。

5.1. 最佳实践

渐进式加压:逐步增加负载,避免系统过载,更好理解应用在压力下的行为
真实场景模拟:包含 ramp-up/ramp-down 阶段,确保测试反映真实用户行为
自动化测试:将 k6 集成到 CI/CD 流水线,实现持续性能监控
标签化分类:为 HTTP 请求添加标签,便于结果组织与分析

5.2. 常见陷阱

⚠️ 测试机过载:确保运行 k6 的机器资源充足,否则测试结果会失真
⚠️ 非真实配置:避免使用过高的虚拟用户数或不切实际的请求模式
⚠️ 忽视事后分析:不深入分析结果就无法发现性能问题,错失优化机会

6. 结论

本文系统介绍了 k6 的环境搭建、真实测试场景创建、结果分析方法及最佳实践。

负载测试不仅是压力测试,更是理解系统行为、确保其能处理真实流量的关键手段。

凭借 k6 的直观脚本、内置指标和灵活配置,我们能够:

  • 模拟真实流量模式
  • 精准评估性能表现
  • 为系统有效扩容做好准备

建议从小规模测试开始,逐步尝试高级场景,持续优化测试策略以适应不断变化的流量需求。


原始标题:How to Execute Load Tests Using the k6 Framework | Baeldung