DEV Community

Cover image for Kiểm thử tải k6: Cẩm nang thực tế cho API
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

Kiểm thử tải k6: Cẩm nang thực tế cho API

Nếu API của bạn chạy ổn với một người dùng nhưng bắt đầu chậm hoặc lỗi khi lưu lượng tăng, hãy thêm kiểm thử tải vào quy trình phát triển. k6 là một lựa chọn gọn, dễ script và phù hợp để kiểm tra API theo cách lặp lại được. Bài viết này hướng dẫn cách cài đặt k6, viết script đầu tiên, cấu hình VU/giai đoạn/ngưỡng, đọc kết quả và kết hợp k6 với kiểm thử chức năng trong CI như một phần của quy trình kiểm thử hiệu suất API. Các phần liên quan đến k6 dựa trên tài liệu k6 chính thức.

Thử Apidog ngay hôm nay

k6 là gì?

k6 là một công cụ kiểm thử tải mã nguồn mở, hiện được duy trì bởi Grafana. Bạn viết bài kiểm thử bằng JavaScript, còn k6 chạy script đó bằng runtime viết bằng Go để tạo tải lên các endpoint.

k6 load testing overview

Cách tiếp cận này giúp bạn:

  • Viết test bằng JavaScript quen thuộc.
  • Chạy tải lớn hơn nhờ engine Go đã biên dịch.
  • Đo latency, throughput, error rate và percentile.
  • Đặt điều kiện pass/fail bằng threshold để dùng trong CI.

k6 tập trung vào một việc: tạo tải có kiểm soát và đo phản ứng của hệ thống. Nó không thay thế công cụ thiết kế API, tài liệu API hay kiểm thử chức năng.

Các khái niệm cần nắm trước khi viết script:

  • VU, Virtual User: người dùng ảo chạy script trong vòng lặp.
  • Iteration: một lần chạy đầy đủ hàm test.
  • Stage: một bước trong hồ sơ tải, dùng để tăng hoặc giảm số VU theo thời gian.
  • Threshold: điều kiện pass/fail trên metric, ví dụ p(95)<500.
  • Check: xác nhận mềm trên response, ví dụ status phải là 200. Check fail được ghi nhận nhưng không dừng test.

Cài đặt k6

k6 được phân phối dưới dạng binary, nên cài đặt khá nhanh.

macOS

brew install k6
Enter fullscreen mode Exit fullscreen mode

Windows

choco install k6
Enter fullscreen mode Exit fullscreen mode

Debian hoặc Ubuntu

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-get update
sudo apt-get install k6
Enter fullscreen mode Exit fullscreen mode

Kiểm tra cài đặt:

k6 version
Enter fullscreen mode Exit fullscreen mode

Nếu không muốn cài trực tiếp trên máy, bạn có thể chạy k6 bằng Docker image chính thức. Với môi trường CI, Docker thường giúp phiên bản k6 nhất quán hơn giữa các pipeline.

Viết script k6 đầu tiên

Một test k6 là một module JavaScript export hàm default. k6 gọi hàm này cho mỗi iteration của mỗi VU.

Tạo file script.js:

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

export default function () {
  const res = http.get('https://test-api.example.com/users');

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

  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

Chạy test:

k6 run script.js
Enter fullscreen mode Exit fullscreen mode

Mặc định, k6 chạy 1 VU với 1 iteration. Dòng sleep(1) mô phỏng thời gian người dùng tạm dừng giữa các hành động. Nếu bỏ sleep, mỗi VU sẽ gửi request nhanh nhất có thể, phù hợp cho kiểm thử throughput thô nhưng ít giống hành vi người dùng thật.

check() là xác nhận mềm. Nếu check fail, k6 vẫn tiếp tục chạy để bạn thấy hệ thống suy giảm như thế nào dưới tải.

Cấu hình VU, duration và stage

Để tạo tải thực tế hơn, thêm options vào script.

Ví dụ chạy 50 VU trong 30 giây:

export const options = {
  vus: 50,
  duration: '30s',
};
Enter fullscreen mode Exit fullscreen mode

Ví dụ hồ sơ tải có ramp-up, giữ tải và ramp-down:

export const options = {
  stages: [
    { duration: '1m', target: 100 }, // tăng lên 100 VU
    { duration: '3m', target: 100 }, // giữ 100 VU
    { duration: '1m', target: 0 },   // giảm về 0
  ],
};
Enter fullscreen mode Exit fullscreen mode

Bạn có thể đặt options cùng file với hàm test:

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

export const options = {
  stages: [
    { duration: '1m', target: 100 },
    { duration: '3m', target: 100 },
    { duration: '1m', target: 0 },
  ],
};

export default function () {
  const res = http.get('https://test-api.example.com/users');

  check(res, {
    'status is 200': (r) => r.status === 200,
  });

  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

Thêm threshold để dùng trong CI

Threshold biến bài kiểm thử tải thành cổng pass/fail rõ ràng. Nếu threshold fail, k6 exit với mã khác 0, nhờ đó CI có thể fail pipeline.

Ví dụ:

export const options = {
  stages: [
    { duration: '1m', target: 100 },
    { duration: '3m', target: 100 },
    { duration: '1m', target: 0 },
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'], // 95% request dưới 500ms
    http_req_failed: ['rate<0.01'],   // dưới 1% request lỗi
  },
};
Enter fullscreen mode Exit fullscreen mode

Với cấu hình này, build sẽ fail nếu:

  • p95 latency từ 500ms trở lên.
  • Error rate từ 1% trở lên.

Đây là cách bạn mã hóa “ngân sách hiệu suất” giống như cách mã hóa assertion trong test chức năng.

Chọn loại hồ sơ tải phù hợp

Hồ sơ Mục tiêu Điều nó cho bạn biết
Smoke test Tải nhỏ, xác minh script chạy đúng Bản thân bài test có hợp lệ không
Load test Lưu lượng bình thường dự kiến API có ổn trong điều kiện hằng ngày không
Stress test Vượt qua mức tải đỉnh dự kiến Hệ thống bắt đầu hỏng ở đâu
Spike test Tăng VU đột ngột API có chịu được lưu lượng tăng bất ngờ không
Soak test Tải vừa phải trong nhiều giờ Có rò rỉ bộ nhớ hoặc suy giảm chậm không

Nếu mới bắt đầu, hãy làm theo thứ tự:

  1. Smoke test để xác minh script.
  2. Load test với traffic gần production.
  3. Stress hoặc spike test khi đã biết baseline.
  4. Soak test nếu nghi ngờ lỗi tích lũy theo thời gian.

Để hiểu thêm về phương pháp và metric, xem các nguyên tắc cơ bản của kiểm thử hiệu suất.

Đọc kết quả k6

Sau khi chạy xong, k6 in summary ra terminal. Các metric quan trọng nhất:

  • http_req_duration: tổng thời gian request, gồm avg, min, max, med, p90, p95.
  • http_req_failed: tỷ lệ request lỗi.
  • http_reqs: tổng số request và request/giây.
  • iterations: số iteration hoàn thành.
  • vus / vus_max: số VU đang hoạt động và tối đa.
  • checks: tỷ lệ pass của các check().

Khi phân tích kết quả, ưu tiên percentile thay vì average.

Ví dụ:

  • Average: 200ms
  • p95: 480ms
  • p99: 4s

Average có vẻ tốt, nhưng p99 cho thấy 1% request chậm nhất mất tới 4 giây. Đây thường là nhóm trải nghiệm gây phàn nàn hoặc rời bỏ sản phẩm.

Nếu chỉ chạy test nhanh, summary trên terminal là đủ. Nếu cần theo dõi nhiều lần chạy, k6 có thể xuất JSON/CSV hoặc tích hợp với Grafana và Prometheus để vẽ biểu đồ theo thời gian.

Ví dụ script k6 hoàn chỉnh

Dưới đây là một script thực tế hơn, có stage, threshold và check response:

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

export const options = {
  stages: [
    { duration: '30s', target: 20 },
    { duration: '1m', target: 50 },
    { duration: '30s', target: 0 },
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'],
    http_req_failed: ['rate<0.01'],
    checks: ['rate>0.99'],
  },
};

export default function () {
  const res = http.get('https://test-api.example.com/users');

  check(res, {
    'status is 200': (r) => r.status === 200,
    'response time < 500ms': (r) => r.timings.duration < 500,
    'body is not empty': (r) => r.body && r.body.length > 0,
  });

  sleep(1);
}
Enter fullscreen mode Exit fullscreen mode

Chạy:

k6 run script.js
Enter fullscreen mode Exit fullscreen mode

Nếu muốn dùng trong CI, giữ threshold ở mức phản ánh SLO hoặc kỳ vọng thực tế của môi trường staging.

Chạy k6 trong CI/CD

Trong pipeline, bạn có thể thêm một step đơn giản:

k6 run script.js
Enter fullscreen mode Exit fullscreen mode

Ví dụ GitHub Actions tối giản:

name: k6-load-test

on:
  workflow_dispatch:

jobs:
  load-test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Install k6
        run: |
          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-get update
          sudo apt-get install k6

      - name: Run load test
        run: k6 run script.js
Enter fullscreen mode Exit fullscreen mode

Thực hành tốt:

  • Chạy load test trên staging, không chạy trực tiếp vào production nếu chưa có kiểm soát.
  • Dùng dữ liệu test riêng.
  • Đặt threshold rõ ràng cho p95 latency và error rate.
  • Không chạy load test nặng trên mỗi commit nếu môi trường staging không đủ ổn định.
  • Chạy smoke/load nhẹ thường xuyên, còn stress/spike theo lịch hoặc trước release.

Vị trí của k6 và vị trí của Apidog

k6 trả lời câu hỏi: API hoạt động thế nào dưới tải liên tục?

Nó không trả lời đầy đủ các câu hỏi như:

  • API có trả về đúng schema không?
  • Response có đúng dữ liệu nghiệp vụ không?
  • Auth, header, token và contract có đúng không?
  • Thay đổi mới có làm hỏng endpoint hiện có không?

Đó là phần của kiểm thử chức năng và kiểm thử hợp đồng.

Mối quan tâm Công cụ phù hợp Câu hỏi được trả lời
Tải lớn, latency percentile, throughput k6 API có duy trì tốc độ dưới lưu lượng không
Tính đúng đắn chức năng, contract, xác thực Apidog API có trả về đúng thứ không
Regression trong CI trên mỗi commit Apidog với apidog run Thay đổi này có làm hỏng endpoint không
Ngân sách hiệu suất trong CI Threshold của k6 Latency hoặc lỗi có vượt giới hạn không

Apidog xử lý phần chính xác của API. Bạn có thể thiết kế hoặc nhập API, xây dựng test scenario với assertion trực quan và chạy trong CI bằng apidog run.

Xem thêm hướng dẫn CLI của Apidog để tích hợp test chức năng vào pipeline. Apidog cũng có các tính năng kiểm thử hiệu suất nhẹ cho kiểm tra nhanh, được trình bày trong hướng dẫn kiểm thử hiệu suất API trong Apidog, nhưng nó không phải trình tạo tải chuyên dụng như k6.

Một workflow thực tế:

  1. Trên mỗi commit, chạy test chức năng và contract bằng Apidog.
  2. Theo lịch hoặc trước release, chạy k6 trên staging.
  3. Dùng threshold k6 để fail pipeline nếu latency/error rate vượt giới hạn.
  4. Chỉ release khi cả correctness gate và performance gate đều pass.

Nếu bạn đang so sánh công cụ, k6 thường được đặt cạnh JMeter, Gatling và Locust. Xem tổng quan về các công cụ kiểm thử tảiso sánh các lựa chọn thay thế Locust để hiểu trade-off về ngôn ngữ script, khả năng mở rộng và cách vận hành.

Các câu hỏi thường gặp

k6 có miễn phí không?

Có. k6 là mã nguồn mở theo giấy phép AGPL và binary có thể chạy cục bộ miễn phí. Giới hạn chính là tài nguyên phần cứng của máy chạy test. Grafana cũng cung cấp k6 Cloud trả phí cho kiểm thử phân tán và lưu trữ kết quả, nhưng bạn không bắt buộc phải dùng dịch vụ đó. Nếu muốn xem thêm lựa chọn miễn phí, tham khảo tổng quan về các công cụ kiểm thử tải.

Tôi có cần biết JavaScript để dùng k6 không?

Có, nhưng chỉ cần mức cơ bản. Phần lớn script k6 gồm:

  • Một hàm default.
  • Một vài lệnh gọi http.get() hoặc http.post().
  • Một số check().
  • Một object options.

Bạn không cần setup framework hoặc build step phức tạp.

Sự khác biệt giữa k6 và Apidog trong kiểm thử hiệu suất là gì?

k6 là trình tạo tải chuyên dụng để tạo traffic liên tục, đo latency percentile và kiểm tra ngưỡng hiệu suất. Apidog là nền tảng API tập trung vào thiết kế, kiểm thử chức năng, kiểm thử hợp đồng và CI test bằng apidog run, đồng thời có kiểm thử hiệu suất nhẹ cho kiểm tra nhanh.

Dùng k6 khi bạn cần tải thực tế và threshold hiệu suất. Dùng Apidog khi bạn cần xác minh API đúng contract, đúng dữ liệu và không bị regression.

Tôi có thể chạy k6 trong CI/CD không?

Có. k6 rất phù hợp với CI vì threshold fail sẽ làm process exit với mã khác 0. Một step như sau là đủ:

k6 run script.js
Enter fullscreen mode Exit fullscreen mode

Trong thực tế, nên kết hợp:

apidog run
k6 run script.js
Enter fullscreen mode Exit fullscreen mode

Cách này giúp pipeline kiểm tra cả tính đúng đắn lẫn hiệu suất.

Kết luận

k6 cho bạn một cách gọn và có thể script để đặt tải lên API, đo latency, throughput, error rate và fail CI bằng threshold. Quy trình tối thiểu là: cài k6, viết script JavaScript, cấu hình VU/stage, thêm threshold và đọc percentile.

Giữ kiểm thử tải tách khỏi kiểm thử chức năng. k6 phù hợp để trả lời “API chịu tải tốt không?”, còn Apidog phù hợp để trả lời “API có đúng contract và đúng hành vi không?”. Khi kết hợp cả hai trong CI, bạn có được kiểm soát tốt hơn trước khi phát hành.

Top comments (0)