K6 性能负载测试工具教程

K6 是由 Grafana Labs 维护的现代化负载测试工具,使用 Go 语言构建,通过 JavaScript ES6 脚本定义测试场景。它拥有极低的资源消耗、丰富的协议支持和优秀的 CI/CD 集成能力。本文将介绍如何在搬瓦工 VPS 上部署 K6 并编写专业的性能测试方案。

一、安装 K6

# Ubuntu/Debian
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
  --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | \
  sudo tee /etc/apt/sources.list.d/k6.list
sudo apt update
sudo apt install k6 -y

# CentOS/RHEL
sudo yum install https://dl.k6.io/rpm/repo.rpm -y
sudo yum install k6 -y

# 或使用二进制安装
wget https://github.com/grafana/k6/releases/latest/download/k6-linux-amd64.tar.gz
tar xzf k6-linux-amd64.tar.gz
mv k6-linux-amd64/k6 /usr/local/bin/

# 验证
k6 version

二、第一个测试脚本

cat > test.js <<'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';

// 测试配置
export const options = {
  vus: 10,        // 10 个虚拟用户
  duration: '30s', // 持续 30 秒
};

export default function () {
  const res = http.get('http://localhost/');

  // 检查响应
  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
  });

  sleep(1); // 每次请求间隔 1 秒
}
EOF

# 运行测试
k6 run test.js

三、负载模型配置

3.1 阶梯式负载

cat > stages-test.js <<'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '2m', target: 50 },   // 2 分钟内增加到 50 用户
    { duration: '5m', target: 50 },   // 保持 50 用户 5 分钟
    { duration: '2m', target: 100 },  // 2 分钟内增加到 100 用户
    { duration: '5m', target: 100 },  // 保持 100 用户 5 分钟
    { duration: '2m', target: 0 },    // 2 分钟内降到 0
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'], // 95% 请求在 500ms 内完成
    http_req_failed: ['rate<0.01'],   // 失败率低于 1%
  },
};

export default function () {
  const res = http.get('http://localhost/');
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
  sleep(1);
}
EOF

3.2 恒定请求速率

cat > constant-rate.js <<'EOF'
import http from 'k6/http';
import { check } from 'k6';

export const options = {
  scenarios: {
    constant_request_rate: {
      executor: 'constant-arrival-rate',
      rate: 100,           // 每秒 100 个请求
      timeUnit: '1s',
      duration: '5m',
      preAllocatedVUs: 50,
      maxVUs: 200,
    },
  },
};

export default function () {
  const res = http.get('http://localhost/');
  check(res, {
    'status is 200': (r) => r.status === 200,
  });
}
EOF

四、高级测试场景

4.1 API 测试(POST/PUT/DELETE)

cat > api-test.js <<'EOF'
import http from 'k6/http';
import { check, group, sleep } from 'k6';

const BASE_URL = 'http://localhost:8080/api';

export const options = {
  vus: 20,
  duration: '3m',
};

export default function () {
  group('User API', function () {
    // 创建用户
    const createRes = http.post(`${BASE_URL}/users`, JSON.stringify({
      name: `user_${__VU}_${__ITER}`,
      email: `user${__VU}@example.com`,
    }), {
      headers: { 'Content-Type': 'application/json' },
    });

    check(createRes, {
      'user created': (r) => r.status === 201,
    });

    const userId = createRes.json('id');

    // 获取用户
    if (userId) {
      const getRes = http.get(`${BASE_URL}/users/${userId}`);
      check(getRes, {
        'user found': (r) => r.status === 200,
      });

      // 删除用户
      const delRes = http.del(`${BASE_URL}/users/${userId}`);
      check(delRes, {
        'user deleted': (r) => r.status === 204,
      });
    }
  });

  sleep(1);
}
EOF

4.2 带认证的测试

cat > auth-test.js <<'EOF'
import http from 'k6/http';
import { check } from 'k6';

export function setup() {
  // setup 阶段只执行一次,获取 token
  const loginRes = http.post('http://localhost:8080/api/login', JSON.stringify({
    username: 'admin',
    password: 'password',
  }), {
    headers: { 'Content-Type': 'application/json' },
  });

  return { token: loginRes.json('token') };
}

export default function (data) {
  const params = {
    headers: {
      'Authorization': `Bearer ${data.token}`,
      'Content-Type': 'application/json',
    },
  };

  const res = http.get('http://localhost:8080/api/protected', params);
  check(res, {
    'authenticated request succeeded': (r) => r.status === 200,
  });
}
EOF

五、阈值与自动判定

cat > threshold-test.js <<'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';

// 自定义指标
const errorRate = new Rate('errors');
const apiDuration = new Trend('api_duration');

export const options = {
  vus: 50,
  duration: '5m',
  thresholds: {
    http_req_duration: ['p(95)<300', 'p(99)<500'],
    http_req_failed: ['rate<0.01'],
    errors: ['rate<0.05'],
    api_duration: ['p(95)<200'],
  },
};

export default function () {
  const res = http.get('http://localhost/api/data');

  const result = check(res, {
    'status 200': (r) => r.status === 200,
    'body not empty': (r) => r.body.length > 0,
  });

  errorRate.add(!result);
  apiDuration.add(res.timings.duration);

  sleep(0.5);
}
EOF

# 运行(阈值不满足时 k6 返回非零退出码)
k6 run threshold-test.js
echo "Exit code: $?"

六、输出与报告

# 输出 JSON 格式结果
k6 run --out json=results.json test.js

# 输出 CSV 格式
k6 run --out csv=results.csv test.js

# 输出到 InfluxDB(配合 Grafana 可视化)
k6 run --out influxdb=http://localhost:8086/k6 test.js

# 生成摘要报告到文件
k6 run --summary-export=summary.json test.js

七、与 CI/CD 集成

# GitHub Actions 示例
cat > .github/workflows/load-test.yml <<'EOF'
name: Load Test
on: [push]
jobs:
  k6-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: grafana/k6-action@v0.3.1
        with:
          filename: test.js
          flags: --vus 50 --duration 30s
EOF

总结

K6 将 JavaScript 的灵活性与 Go 的高性能完美结合,是现代化性能测试的首选工具。它的阈值功能特别适合集成到 CI/CD 流水线中,自动化性能回归检测。简单的基准测试也可以使用 wrk,模拟复杂用户行为可以使用 Locust。选购搬瓦工 VPS 请查看 全部方案,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的折扣,通过 bwh81.net 访问官网。

关于本站

搬瓦工VPS中文网(bwgvps.com)是非官方中文信息站,整理搬瓦工的方案、优惠和教程。我们不销售主机,不提供技术服务。

新手必读
搬瓦工优惠码

NODESEEK2026(优惠 6.77%)

购买时填入即可抵扣。