Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tuannguyen29/d5e3787975ac3367f6a0c49e611c6462 to your computer and use it in GitHub Desktop.
Save tuannguyen29/d5e3787975ac3367f6a0c49e611c6462 to your computer and use it in GitHub Desktop.
kỹ thuật load test các request trong lập trình là gì

Load testing requests với k6 trên Ubuntu 22.04

Dưới đây là tóm tắt các kỹ thuật “load test” (kiểm thử tải) cho request trong lập trình và hệ thống web/API:

1) Khái niệm và mục tiêu

  • Load testing: Đo khả năng hệ thống xử lý tải mong đợi (số request/giây, số người dùng đồng thời) với tỉ lệ lỗi và độ trễ chấp nhận được.
  • Liên quan:
    • Stress test: Đẩy quá tải để tìm ngưỡng sập và hành vi khi quá tải.
    • Spike test: Tải tăng đột biến trong thời gian ngắn.
    • Soak/Endurance test: Chạy tải vừa phải lâu dài để phát hiện rò rỉ tài nguyên.
    • Capacity test: Xác định mức tải tối đa trước khi vi phạm SLO.

2) Chỉ số quan trọng cần theo dõi

  • RPS/QPS (request/giây), số user đồng thời (concurrency).
  • Độ trễ theo phân vị: p50, p90, p95, p99, max; TTFB.
  • Tỉ lệ lỗi (HTTP 5xx/4xx), timeouts, retries.
  • Tài nguyên: CPU, RAM, I/O, GC, băng thông, connection pool, thread/worker.
  • Phụ thuộc ngoài: DB (latency, locks), cache, message queue, dịch vụ downstream.
  • SLO/SLA: ví dụ p95 < 300 ms, lỗi < 0.1%.

3) Mô hình tải

  • Open model (arrival-rate): Điều khiển tốc độ đến (ví dụ 100 RPS). Phù hợp hệ thống web công khai.
  • Closed model (vus/users): Điều khiển số người dùng ảo, mỗi user có think-time. Phù hợp mô phỏng phiên người dùng.
  • Hình dạng tải: ramp-up, steady-state, ramp-down; spike; step; sinus.
  • Warm-up: chạy nhẹ để làm nóng cache/JIT/opcache trước khi đo.

4) Quy trình thực hiện

  • Xác định mục tiêu: SLO, kịch bản sử dụng, dữ liệu thực tế.
  • Thiết kế kịch bản: Đường đi người dùng, tỉ lệ endpoint, think-time, phân phối payload, tham số hóa và tương quan (correlation) token/session.
  • Dữ liệu: Data set đủ lớn, ID duy nhất để tránh cache giả, idempotency khi POST.
  • Môi trường: Gần giống production (cấu hình, dữ liệu, phiên bản). Tắt/bật cache tùy mục tiêu (cold vs warm).
  • Thực thi: Ramp-up từ từ, giữ steady >= 10–30 phút (hoặc lâu hơn với soak), dừng theo điều kiện lỗi/latency.
  • Quan sát: Log + APM + tracing + metrics (Prometheus/Grafana). Gắn nhãn test để phân tích.
  • Phân tích: Tìm “plateau” throughput, điểm gãy p95/p99, lỗi tăng, tài nguyên bão hòa. Áp dụng Little’s Law (L = λ W) để suy luận hàng đợi.
  • Lặp lại: Tối ưu (DB index, cache, pool, batching), đo lại.

5) Kỹ thuật thực hành tốt

  • Parameterization và correlation: Trích token CSRF/JWT từ response và dùng cho request tiếp theo.
  • Think-time và pacing: Mô phỏng hành vi người dùng thật.
  • Connection reuse: HTTP/1.1 keep-alive, HTTP/2, gRPC; TLS session reuse.
  • Retries với backoff + jitter; tôn trọng rate limit.
  • Phân tách đọc/ghi; thử với cache cold vs warm.
  • Test lỗi từng phần: Circuit breaker, timeouts, bulkhead, chaos (latency injection).
  • Phân tán generator: Nhiều injector để tránh nghẽn client (CPU, NIC).
  • Tránh “coordinated omission”: Ưu tiên open model (RPS cố định) khi đo latency.
  • Dọn state: Reset dữ liệu, cleanup để run lặp lại nhất quán.

6) Công cụ phổ biến

  • Kịch bản phong phú:
    • k6 (JavaScript), Locust (Python), Gatling (Scala), Artillery (YAML/JS).
  • Đơn giản/CLI:
    • wrk, vegeta, hey, ab (ApacheBench).
  • Trình duyệt/end-to-end:
    • Playwright/Test + tracing; nhưng không thay thế API load test.
  • APM/Observability:
    • OpenTelemetry, Jaeger, Prometheus/Grafana.

7) Ví dụ nhanh

k6 (open model theo RPS)

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

export const options = {
  scenarios: {
    steady_rps: {
      executor: 'constant-arrival-rate',
      rate: 200, // 200 RPS
      timeUnit: '1s',
      duration: '10m',
      preAllocatedVUs: 50,
      maxVUs: 200,
    },
  },
  thresholds: {
    http_req_duration: ['p(95)<300'],
    http_req_failed: ['rate<0.001'],
  },
};

export default function () {
  const res = http.get('https://api.example.com/items?limit=20');
  check(res, { 'status is 200': r => r.status === 200 });
  sleep(1); // think-time (tác dụng trong closed model)
}

Locust (closed model theo số user):

from locust import HttpUser, task, between

class WebsiteUser(HttpUser):
    wait_time = between(1, 3)  # think-time
    @task(3)
    def list_items(self):
        self.client.get("/items?limit=20")
    @task(1)
    def create_item(self):
        self.client.post("/items", json={"name": "foo"})

8) Cách đọc kết quả

  • Throughput “plateau” dù tăng tải => nghẽn tài nguyên (CPU, DB, pool).
  • p95/p99 tăng mạnh khi tăng tải nhẹ => đụng hàng đợi.
  • Lỗi 5xx/timeout tăng cùng latency => quá tải hoặc cấu hình timeout/pool nhỏ.
  • Soak test: memory tăng dần, GC/FD leak => rò rỉ tài nguyên.

9) Lỗi thường gặp

  • Test từ máy yếu/băng thông thấp => nghẽn ở client.
  • Dữ liệu lặp lại gây cache hit bất thường.
  • Bỏ qua warm-up hoặc chạy quá ngắn.
  • Chỉ nhìn trung bình, bỏ p95/p99.
  • Không tách ảnh hưởng CDN/WAF/Rate limit.

Gợi ý cho ứng dụng PHP/Laravel/Phalcon

  • PHP-FPM, DB, Nginx, cache...
  • Dùng k6/Locust để mô phỏng mix đọc/ghi, theo dõi p95/p99 và tỉ lệ lỗi.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment