DEV Community

Cover image for autocannon: Kiểm thử tải HTTP Node.js (Hướng dẫn từng bước)
Sebastian Petrus
Sebastian Petrus

Posted on • Originally published at apidog.com

autocannon: Kiểm thử tải HTTP Node.js (Hướng dẫn từng bước)

Bạn đã viết một endpoint HTTP. Nó chạy ổn khi gọi một lần từ Postman. Nhưng khi 200 client gọi cùng lúc thì sao? Bạn cần đo request/giây, phân vị độ trễ và số phản hồi không phải 2xx. autocannon giúp lấy các số liệu đó trực tiếp từ terminal trong khoảng vài giây.

Dùng thử Apidog hôm nay

autocannon là công cụ benchmark HTTP/1.1 viết bằng Node.js. Nó tạo tải có kiểm soát đến một URL, sau đó báo cáo throughput, latency và lỗi. Bài viết này hướng dẫn cách cài đặt, chạy test cơ bản, dùng các flag quan trọng, đọc kết quả và nhúng autocannon vào script Node.js để dùng trong CI.

autocannon là gì

autocannon mở một số lượng kết nối đồng thời cố định đến một URL, sau đó liên tục gửi request trong một khoảng thời gian hoặc cho đến khi đạt đủ số request. Khi chạy xong, nó in ra bảng phân vị độ trễ và tổng số request/byte đã xử lý.

Nó trả lời một câu hỏi rất cụ thể:

Server xử lý được bao nhiêu tải và phản hồi nhanh thế nào khi đang chịu tải?

không kiểm tra response có đúng dữ liệu không, API có khớp OpenAPI spec không, hoặc workflow nhiều bước có chạy đúng logic không. Vì vậy, hãy dùng autocannon cho kiểm thử tải, còn kiểm thử chức năng/hợp đồng nên xử lý bằng công cụ khác.

Nếu bạn từng dùng wrk hoặc Apache Bench, autocannon nằm cùng nhóm công cụ, nhưng thân thiện hơn với hệ sinh thái Node.js và có API JavaScript để tự động hóa.

Cài đặt

Cài global để dùng lệnh autocannon ở mọi nơi:

npm i autocannon -g
Enter fullscreen mode Exit fullscreen mode

Bạn cần cài Node.js trước. Nếu không muốn cài global, chạy bằng npx:

npx autocannon http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Hoặc thêm vào project như dev dependency nếu bạn muốn viết script:

npm i autocannon --save-dev
Enter fullscreen mode Exit fullscreen mode

Kiểm tra cài đặt:

autocannon --version
Enter fullscreen mode Exit fullscreen mode

Chạy benchmark cơ bản

Lệnh đơn giản nhất:

autocannon http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Mặc định, lệnh này chạy:

  • 10 kết nối đồng thời
  • Trong 10 giây
  • Gửi request nhanh nhất có thể

Ba flag bạn sẽ dùng thường xuyên nhất:

  • -c: số kết nối đồng thời
  • -d: thời lượng chạy, tính bằng giây
  • -p: HTTP pipelining, tức số request mỗi connection gửi trước khi chờ response

Ví dụ:

autocannon -c 100 -d 30 -p 10 http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Lệnh này mở 100 connection, chạy trong 30 giây và dùng pipelining 10 request mỗi connection. Tăng -c-p giúp tạo tải lớn hơn để tìm điểm mà latency bắt đầu tăng mạnh.

Nếu muốn gửi một số lượng request cố định thay vì chạy theo thời gian, dùng -a:

autocannon -c 10 -a 10000 http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Lệnh này dừng sau khi hoàn thành 10.000 request.

Gửi POST request, header và body

Dùng:

  • -m để đổi HTTP method
  • -H để thêm header
  • -b để truyền body trực tiếp

Ví dụ POST JSON:

autocannon -c 50 -d 20 \
  -m POST \
  -H 'Content-Type=application/json' \
  -H 'Authorization=Bearer YOUR_TOKEN' \
  -b '{"name":"load-test","active":true}' \
  http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Định dạng header là:

-H 'Key=Value'
Enter fullscreen mode Exit fullscreen mode

Nếu body lớn hoặc đã nằm trong file, dùng -i:

autocannon -m POST \
  -H 'Content-Type=application/json' \
  -i payload.json \
  http://localhost:3000/api/users
Enter fullscreen mode Exit fullscreen mode

Giới hạn request/giây

Mặc định, autocannon gửi request nhanh nhất có thể. Nếu bạn muốn mô phỏng tải ổn định hơn, dùng -R để đặt tổng request/giây trên toàn bộ connection:

autocannon -c 50 -R 500 -d 60 http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Lệnh này giữ tải ở mức 500 request/giây trong 60 giây.

Cách dùng thực tế:

  • Dùng -R để đo latency ở mức tải kỳ vọng trong production.
  • Không dùng -R nếu mục tiêu là tìm điểm nghẽn tối đa của server.

Warmup và worker

Hai flag hữu ích khi benchmark nặng hơn:

  • -W: warmup trước khi bắt đầu lấy mẫu
  • -w: dùng nhiều worker thread để tạo tải

Ví dụ:

autocannon -c 200 -d 30 -w 4 http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Warmup giúp tránh số liệu bị lệch do cache lạnh hoặc JIT chưa khởi động.

Chỉ dùng -w khi bạn đã xác nhận chính máy tạo tải là bottleneck. Nếu tăng -c nhưng throughput không tăng, trong khi CPU của máy chạy autocannon đã cao, hãy thử thêm worker.

Đọc kết quả autocannon

Ví dụ output rút gọn:

Running 10s test @ http://localhost:3000
10 connections

┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬──────────┐
│ Stat    │ 2.5% │ 50%  │ 97.5% │ 99%  │ Avg     │ Stdev   │ Max      │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼──────────┤
│ Latency │ 0 ms │ 1 ms │ 4 ms  │ 6 ms │ 1.2 ms  │ 0.9 ms  │ 24.1 ms  │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴──────────┘

251k requests in 10.05s, 27.9 MB read
Enter fullscreen mode Exit fullscreen mode

Cách đọc nhanh:

  • 50%: median latency.
  • 97.5%99%: tail latency. Đây thường là phần quan trọng nhất.
  • Avg: latency trung bình.
  • Stdev: độ phân tán. Stdev cao nghĩa là response time không ổn định.
  • 251k requests in 10.05s: tổng request đã xử lý. Chia request cho số giây để có request/giây.

Để xem phân vị chi tiết hơn, thêm -l:

autocannon -c 100 -d 20 -l http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Để xem phân bố status code, thêm --renderStatusCodes:

autocannon -c 100 -d 20 -l --renderStatusCodes http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Luôn kiểm tra:

  • non2xx
  • errors
  • timeouts
  • status code 4xx/5xx

Một server có thể đạt throughput cao nhưng đang trả về lỗi. Khi đó, con số request/giây không còn phản ánh số request thành công.

Dùng autocannon trong script Node.js

autocannon có API Node.js, phù hợp để tự động hóa benchmark trong CI hoặc script nội bộ.

Ví dụ cơ bản:

const autocannon = require('autocannon')

async function run() {
  const result = await autocannon({
    url: 'http://localhost:3000',
    connections: 100,
    duration: 20,
    pipelining: 1
  })

  console.log(`Độ trễ trung bình: ${result.latency.average} ms`)
  console.log(`Yêu cầu/giây: ${result.requests.average}`)
  console.log(`Không phải 2xx: ${result.non2xx}`)
}

run()
Enter fullscreen mode Exit fullscreen mode

result chứa các nhóm số liệu như:

  • latency
  • requests
  • throughput
  • errors
  • timeouts
  • non2xx

Các histogram như latency có các trường như:

  • average
  • min
  • max
  • p99

Tạo performance gate trong CI

Bạn có thể fail build nếu p99 vượt ngân sách hoặc có response không phải 2xx:

const autocannon = require('autocannon')

const P99_BUDGET_MS = 250

async function run() {
  const result = await autocannon({
    url: 'http://localhost:3000/api/health',
    connections: 100,
    duration: 30
  })

  const p99 = result.latency.p99
  console.log(`Độ trễ p99: ${p99} ms (ngân sách ${P99_BUDGET_MS} ms)`)

  if (p99 > P99_BUDGET_MS || result.non2xx > 0) {
    console.error('Ngân sách hiệu suất đã bị vượt quá')
    process.exit(1)
  }
}

run()
Enter fullscreen mode Exit fullscreen mode

Đây là cách biến benchmark thành kiểm tra pass/fail trong pipeline.

Hiển thị progress như CLI

Nếu muốn có progress bar và bảng kết quả giống CLI, dùng autocannon.track:

const autocannon = require('autocannon')

const instance = autocannon({
  url: 'http://localhost:3000',
  connections: 10,
  duration: 10
}, console.log)

autocannon.track(instance, { renderProgressBar: true })

process.once('SIGINT', () => instance.stop())
Enter fullscreen mode Exit fullscreen mode

Chạy nhiều request trong một kịch bản

Bạn có thể truyền mảng requests để mỗi connection lặp qua nhiều call:

autocannon({
  url: 'http://localhost:3000',
  connections: 20,
  duration: 15,
  requests: [
    {
      method: 'GET',
      path: '/api/users'
    },
    {
      method: 'POST',
      path: '/api/data',
      body: '{"x":1}',
      headers: {
        'Content-Type': 'application/json'
      }
    }
  ]
}, console.log)
Enter fullscreen mode Exit fullscreen mode

Cách này hữu ích khi bạn muốn benchmark một flow đơn giản thay vì chỉ một endpoint.

autocannon so với wrk và ab

Cả ba công cụ đều trả lời câu hỏi:

API nhanh đến mức nào dưới một mức tải nhất định?

Khác biệt chính:

  • Apache Bench (ab): đơn giản, phổ biến, nhưng cũ và đơn luồng.
  • wrk: rất nhanh, hỗ trợ Lua script, phù hợp để tạo tải lớn.
  • autocannon: dễ dùng nếu bạn ở hệ sinh thái Node.js, cài bằng npm, có API JavaScript, hỗ trợ pipelining, HAR file và scripting.

Nếu runtime chính của bạn là Node.js, autocannon thường là lựa chọn ít ma sát nhất.

Tham khảo thêm:

Kiểm thử chức năng và Apidog phù hợp ở đâu

autocannon có thể cho bạn biết endpoint phục vụ 12.000 request/giây với p99 là 40 ms. Nhưng nó không cho bạn biết response có đúng không.

Một bài kiểm thử tải có thể pass dù API:

  • Trả JSON sai định dạng
  • Bỏ qua header xác thực
  • Lệch khỏi hợp đồng OpenAPI
  • Trả dữ liệu sai trong một workflow nhiều bước

Đây là phần mà kiểm thử chức năng và kiểm thử hợp đồng xử lý. Apidog bổ sung cho công cụ load test, không thay thế nó.

Apidog không phải là trình tạo tải. Nó chạy các test scenario đã lưu với assertion về:

  • Status code
  • Response schema
  • Response value
  • Luồng nhiều bước

Trong CI, hai loại kiểm thử này trả lời hai câu hỏi khác nhau:

  • autocannon: API có đủ nhanh dưới tải không?
  • Apidog CLI: API có hoạt động đúng không?

Ví dụ chạy Apidog CLI:

npm install -g apidog-cli

apidog run \
  --access-token "$APIDOG_ACCESS_TOKEN" \
  -t <scenarioOrSuiteId> \
  -e <environmentId> \
  -r cli,html,junit
Enter fullscreen mode Exit fullscreen mode

Trong đó:

  • -t: chọn scenario, folder hoặc test suite theo ID
  • -e: chọn environment
  • -r: chọn reporter, ví dụ cli, html, json, junit

Tham khảo thêm:

Một pipeline thực tế thường chạy:

  1. Kiểm thử chức năng và hợp đồng trên mỗi push.
  2. Kiểm thử tải trước release hoặc trước khi thay đổi hạ tầng lớn.

autocannon chịu trách nhiệm câu hỏi hiệu năng. Apidog chịu trách nhiệm câu hỏi tính đúng đắn.

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

autocannon có chính xác cho kiểm thử tải production không?

autocannon tạo số liệu throughput và latency đáng tin cậy cho endpoint HTTP/1.1. Khi dùng -R, nó đặt tốc độ mục tiêu và xử lý coordinated omission, điều mà nhiều công cụ đơn giản hơn bỏ qua.

Để kết quả hữu ích hơn:

  • Chạy từ máy gần server để giảm nhiễu do network latency.
  • Dùng đủ connection để bão hòa endpoint.
  • Chạy trên staging giống production, không chỉ trên server dev local.
  • Theo dõi CPU/RAM/network của cả server và máy tạo tải.

autocannon có hỗ trợ HTTP/2 hoặc WebSocket không?

Không. autocannon benchmark HTTP/1.1.

Nếu cần kiểm thử tải HTTP/2 hoặc WebSocket, bạn cần công cụ khác. Đây là giới hạn quan trọng cần kiểm tra trước khi chọn autocannon.

Nên dùng bao nhiêu connection?

Bắt đầu với mặc định 10 connection:

autocannon http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Sau đó tăng dần -c:

autocannon -c 50 -d 30 http://localhost:3000
autocannon -c 100 -d 30 http://localhost:3000
autocannon -c 200 -d 30 http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Khi request/giây ngừng tăng nhưng latency bắt đầu tăng mạnh, bạn đã gần điểm giới hạn của server hoặc máy tạo tải.

Có thể chạy autocannon trong CI không?

Có. Dùng API lập trình để đọc result.latency.p99, result.non2xx, result.errors và gọi process.exit(1) nếu vượt ngưỡng.

Ví dụ điều kiện fail thường dùng:

if (
  result.latency.p99 > 250 ||
  result.non2xx > 0 ||
  result.errors > 0
) {
  process.exit(1)
}
Enter fullscreen mode Exit fullscreen mode

Khác biệt giữa -a-d là gì?

-d chạy trong một số giây nhất định:

autocannon -d 30 http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

-a chạy cho đến khi hoàn thành một số request nhất định:

autocannon -a 10000 http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

Dùng -d cho benchmark tải ổn định. Dùng -a khi bạn cần gửi đúng một số lượng request cụ thể.

Top comments (0)