Bạn đã triển khai một endpoint. Nó trả về JSON đúng trong Postman. Nhưng bạn không biết điều gì sẽ xảy ra khi 200 client truy cập nó cùng lúc. Liệu nó có thể xử lý 500 yêu cầu mỗi giây, hay độ trễ sẽ tăng vọt ở mức 50? ApacheBench sẽ trả lời câu hỏi đó chỉ với một lệnh.
ApacheBench, được gọi là ab, là một công cụ dòng lệnh gửi một số lượng cố định các yêu cầu HTTP đến một URL duy nhất và báo cáo thông lượng cũng như độ trễ. Nó được tích hợp với Apache HTTP Server và đã tồn tại hàng thập kỷ. Nó nhỏ gọn, chạy nhanh và cung cấp cho bạn cái nhìn tổng quan nhanh chóng về mức tải mà một endpoint có thể chịu được.
Hướng dẫn này bao gồm cách cài đặt ab, chạy thử nghiệm cơ bản, kiểm tra các endpoint POST, đọc kết quả và biết khi nào ab không còn là công cụ phù hợp. Mỗi lệnh ở đây đều tương ứng với một cờ (flag) được ghi trong tài liệu tham khảo Apache ab chính thức.
ApacheBench là gì và nguồn gốc của nó
ab là một client benchmark được tích hợp với Apache HTTP Server. Tên này là viết tắt của ApacheBench. Nó mở các kết nối đến một URL, gửi các yêu cầu nhanh nhất có thể theo cài đặt độ đồng thời của bạn, tính thời gian cho mỗi phản hồi và in ra bản tóm tắt.

Nó đo lường tốt một điều: số lượng yêu cầu mỗi giây mà một endpoint có thể xử lý, và cách thời gian phản hồi được phân bố dưới tải. Đó là thông lượng và độ trễ cho một URL.
Điều nó không làm cũng quan trọng không kém. ab không kiểm tra liệu nội dung phản hồi có đúng hay không. Nó không xác thực schema hoặc khẳng định một trường có giá trị mong muốn. Nó không thực hiện một luồng nhiều bước như đăng nhập, sau đó lấy dữ liệu, sau đó cập nhật. Nó chỉ truy cập một URL và đếm. Hãy ghi nhớ phạm vi đó và ab sẽ vẫn hữu ích. Nếu mong đợi nhiều hơn, bạn sẽ thất vọng.
Nếu bạn muốn có cái nhìn rộng hơn về lĩnh vực mà ab phù hợp, hãy xem kiểm thử tải API là gì và tại sao thời gian phản hồi API lại quan trọng.
Cài đặt ab
ab được đóng gói cùng với các tiện ích của Apache. Tên gói khác nhau tùy theo nền tảng.
Trên Debian và Ubuntu, cài đặt gói apache2-utils:
sudo apt-get update
sudo apt-get install -y apache2-utils
Trên CentOS, RHEL và Fedora, gói là httpd-tools:
# CentOS 7
sudo yum install -y httpd-tools
# Fedora and CentOS 8+
sudo dnf install -y httpd-tools
Trên macOS, ab đã có sẵn vì hệ thống đi kèm với Apache. Hãy kiểm tra:
ab -V
Bạn sẽ thấy một dòng phiên bản như Version 2.3. Nếu lệnh bị thiếu trên macOS, hãy cài đặt nó thông qua công thức Apache của Homebrew. Khi ab -V hiển thị phiên bản, bạn đã sẵn sàng.
Chạy kiểm thử tải cơ bản
Hai cờ bạn sẽ luôn sử dụng là -n và -c.
-n requestsđặt tổng số yêu cầu sẽ thực hiện. Mặc định là một yêu cầu duy nhất, điều này không cho bạn biết gì, vì vậy hãy luôn đặt giá trị này.-c concurrencyđặt số lượng yêu cầu chạy cùng một lúc. Mặc định là một, có nghĩa là hoàn toàn tuần tự.
Đây là 1000 yêu cầu, 50 yêu cầu cùng lúc, đối với một endpoint JSON:
ab -n 1000 -c 50 https://api.example.com/v1/users
Lưu ý đường dẫn cuối cùng. ab cần một URL đầy đủ có đường dẫn. Nếu bạn trỏ nó đến một máy chủ trần không có đường dẫn, nó sẽ báo lỗi. Đối với gốc, hãy sử dụng dấu gạch chéo cuối cùng: https://api.example.com/.
Các client thực tế tái sử dụng các kết nối TCP thay vì mở một kết nối mới cho mỗi yêu cầu. Thêm -k để bật HTTP KeepAlive để ab tái sử dụng các kết nối trong một phiên:
ab -n 1000 -c 50 -k https://api.example.com/v1/users
Việc chạy với -k thường gần với cách trình duyệt hoặc client API hoạt động, vì nó tránh phải trả chi phí thiết lập kết nối cho mỗi yêu cầu. Hãy so sánh hai con số để xem bao nhiêu phần trăm độ trễ của bạn là chi phí kết nối.
Bạn cũng có thể giới hạn chạy theo thời gian thay vì số lượng. -t đặt số giây tối đa và ngầm định -n 50000, vì vậy kiểm thử sẽ dừng ở giới hạn nào bạn đạt được trước tiên:
ab -t 30 -c 50 -k https://api.example.com/v1/users
Lệnh này chạy trong tối đa 30 giây với độ đồng thời 50. Tiện lợi khi bạn muốn đo lường trong một khoảng thời gian cố định thay vì số lượng cố định.
Kiểm thử một endpoint POST
Hầu hết công việc API không phải là GET. Để kiểm tra POST, hãy đặt nội dung yêu cầu vào một tệp và truyền nó bằng -p. Bạn cũng phải đặt loại nội dung bằng -T, nếu không máy chủ sẽ từ chối nội dung.
Tạo payload:
cat > payload.json <<'EOF'
{"name": "Ada Lovelace", "email": "ada@example.com"}
EOF
Sau đó gửi nó:
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
https://api.example.com/v1/users
Cờ -p đặt tên tệp chứa nội dung POST. Cờ -T đặt tiêu đề Content-Type. Loại nội dung mặc định là text/plain, hầu như không bao giờ là thứ mà một API JSON mong muốn, vì vậy hãy đặt -T application/json một cách rõ ràng.
Nếu endpoint của bạn cần xác thực hoặc các tiêu đề khác, hãy thêm chúng bằng -H. Lặp lại cờ cho mỗi tiêu đề:
ab -n 500 -c 25 -k \
-p payload.json \
-T application/json \
-H "Authorization: Bearer YOUR_TOKEN" \
https://api.example.com/v1/users
Để ôn lại cách tạo nội dung yêu cầu JSON thủ công, hãy xem cách POST dữ liệu JSON bằng curl. Cùng một nội dung cũng hoạt động như một tệp payload của ab.
Đọc kết quả
Một lần chạy sẽ in ra một khối số. Đây là một ví dụ đã cắt gọn:
Concurrency Level: 50
Time taken for tests: 4.212 seconds
Complete requests: 1000
Failed requests: 0
Non-2xx responses: 0
Requests per second: 237.42 [#/sec] (mean)
Time per request: 210.598 [ms] (mean)
Time per request: 4.212 [ms] (mean, across all concurrent requests)
Transfer rate: 142.31 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 5 18 9.4 16 64
Processing: 22 189 41.2 182 310
Waiting: 21 177 39.8 171 295
Total: 31 207 42.7 201 338
Percentage of the requests served within a certain time (ms)
50% 201
66% 221
75% 236
90% 268
95% 291
99% 324
100% 338 (longest request)
Đọc các trường này trước:
- Yêu cầu mỗi giây (Requests per second) là chỉ số thông lượng chính của bạn. Đó là số lượng yêu cầu chia cho tổng thời gian. Con số càng cao càng tốt.
- Yêu cầu thất bại (Failed requests) và Phản hồi không phải 2xx (Non-2xx responses) cho bạn biết liệu máy chủ có thực sự xử lý được tải hay bắt đầu gặp lỗi. Một số lượng yêu cầu mỗi giây cao không có ý nghĩa gì nếu một nửa phản hồi là 500s. Luôn kiểm tra hai chỉ số này trước khi bạn tin vào số liệu thông lượng.
- Thời gian mỗi yêu cầu (Time per request) xuất hiện hai lần. Dòng đầu tiên là thời gian trung bình mà một người dùng đơn lẻ chờ đợi (độ đồng thời nhân với tổng thời gian chia cho số yêu cầu). Dòng thứ hai, được gắn nhãn "trên tất cả các yêu cầu đồng thời," là khoảng cách trung bình giữa các yêu cầu đã hoàn thành. Con số đầu tiên là thứ mà người dùng cảm nhận.
Bảng Tỷ lệ phần trăm yêu cầu được xử lý trong một khoảng thời gian nhất định (Percentage of the requests served within a certain time) là phần hữu ích nhất. Đó là một phân tích theo phần trăm. Dòng 50% là giá trị trung vị của bạn. Các dòng 95% và 99% cho thấy các trường hợp chậm nhất. Trong ví dụ, một nửa số yêu cầu hoàn thành trong vòng 201ms, nhưng 1% mất 324ms hoặc lâu hơn. Độ trễ ở phần đuôi là nơi người dùng thực sự bị ảnh hưởng, vì vậy hãy theo dõi phân vị thứ 95 và 99 nhiều hơn giá trị trung bình.
Bạn muốn các con số thô cho mỗi yêu cầu để tạo biểu đồ? Thêm -e results.csv để ghi tệp CSV chứa các cặp phần trăm-thời gian, hoặc -g results.tsv cho một tệp thân thiện với gnuplot.
Khi nào ab không còn là công cụ phù hợp
ab có phạm vi hẹp một cách có chủ đích. Những hạn chế của nó đáng được nêu rõ ràng để bạn không lạm dụng nó.
- Một URL cho mỗi lần chạy.
abtập trung vào một endpoint duy nhất. Nó không thể tạo kịch bản cho một chuỗi hành động như xác thực, tạo tài nguyên, sau đó đọc lại. Hành trình người dùng thực tế chạm vào nhiều endpoint theo thứ tự, vàabkhông có khái niệm về điều đó. - Không kiểm tra tính đúng đắn.
abđếm mã trạng thái và độ dài byte. Nó không phân tích cú pháp JSON của bạn hoặc khẳng định rằng một trường bằng một giá trị mong đợi. Một phản hồi có thể sai về cấu trúc nhưng vẫn được tính là thành công. Các con số tải không thể thay thế cho một bộ kiểm thử thành công. - Xử lý HTTP lỗi thời. Tài liệu chính thức ghi rõ
abkhông triển khai đầy đủ HTTP/1.x và chỉ chấp nhận một số dạng phản hồi mong đợi. Nó không hỗ trợ HTTP/2. Đối với các máy chủ hoạt động khác nhau dưới HTTP/2,absẽ không phản ánh được điều đó. - Tải từ một máy duy nhất.
abchạy từ một máy và một tiến trình. Vượt quá một mức độ đồng thời nhất định, bạn sẽ đo lường giới hạn của chính client của mình thay vì của máy chủ. Tài liệu thậm chí còn cảnh báo rằng việc phân tích cú pháp củaabcó thể trở thành một nút thắt cổ chai trong các profile.
Không có điều nào trong số này làm cho ab trở nên tồi tệ. Nó làm cho nó trở thành một công cụ cụ thể: một công cụ kiểm tra thông lượng nhanh cho một endpoint. Khi bạn cần các luồng được kịch bản hóa, tải phân tán hoặc HTTP/2, hãy tìm một công cụ được xây dựng cho mục đích đó. JMeter xử lý các kịch bản nhiều bước và chạy phân tán, và có một danh sách rộng hơn các công cụ kiểm thử tải nếu bạn đang so sánh các lựa chọn.
Vị trí của kiểm thử chức năng
Thông lượng là một khía cạnh. Tính đúng đắn là một khía cạnh khác, và ab không chạm đến nó. Trước khi bạn kiểm thử tải một endpoint, bạn muốn biết nó trả về dữ liệu đúng với cấu trúc đúng trong điều kiện bình thường. Đó là kiểm thử chức năng và kiểm thử hợp đồng, và đó là một công việc khác.
Đây là nơi một nền tảng API đầy đủ khẳng định vị trí của nó bên cạnh ab. Apidog cho phép bạn xây dựng các kịch bản kiểm thử với các khẳng định trực quan, xâu chuỗi các yêu cầu thành các luồng nhiều bước và xác thực phản hồi dựa trên schema của bạn, những điều mà ab không thể làm được theo thiết kế. Bạn lưu các kịch bản đó một lần và chạy chúng ở bất cứ đâu.
Đối với tích hợp liên tục, Apidog CLI chạy các kịch bản đã lưu của bạn mà không cần giao diện người dùng. Cài đặt nó bằng Node:
npm install -g apidog-cli
Sau đó, chạy một kịch bản hoặc bộ kịch bản đã lưu đối với một môi trường đã chọn, tạo ra các báo cáo mà hệ thống CI của bạn có thể lưu trữ:
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
Cờ -t nhắm mục tiêu đến một kịch bản, thư mục hoặc bộ kịch bản đã lưu theo ID. Cờ -e chọn môi trường. Cờ -r chọn một hoặc nhiều trình báo cáo từ cli, html, json và junit. Đối với các lần chạy dựa trên dữ liệu, thêm -d (hoặc --iteration-data) với đường dẫn tệp dữ liệu hoặc ID dữ liệu kiểm thử. CLI không có giao diện người dùng và chạy các kịch bản đã lưu, vì vậy nó phù hợp với bất kỳ bước CI nào có thể chạy Node. Nó không phải là một trình gửi yêu cầu và không phải là một trình tạo tải, nó chạy các kiểm thử chức năng mà ab không bao giờ được thiết kế để chạy.
Một thiết lập lành mạnh sử dụng cả hai. Chạy các kịch bản Apidog để chứng minh endpoint hoạt động đúng. Chạy ab để chứng minh nó đủ nhanh. Về mặt tính đúng đắn, hãy xem hướng dẫn kiểm thử hiệu suất Apidog và hướng dẫn kiểm thử hiệu suất API chung.
Câu hỏi thường gặp
ApacheBench chỉ dành cho máy chủ Apache?
Không. Mặc dù tên gọi, ab gửi các yêu cầu HTTP và HTTPS thuần túy đến bất kỳ máy chủ nào. Nó hoạt động với Nginx, Node, Go, Python hoặc bất kỳ máy chủ nào sử dụng HTTP. Mối liên hệ với Apache chỉ là công cụ này được đi kèm với Apache HTTP Server.
Tôi nên sử dụng mức độ đồng thời và số lượng yêu cầu nào?
Bắt đầu với mức thấp rồi tăng dần. Hãy thử -n 1000 -c 10, sau đó tăng -c lên 25, 50, 100, và quan sát xem tại đâu số lượng yêu cầu mỗi giây ngừng tăng và các yêu cầu thất bại bắt đầu xuất hiện. Điểm uốn đó gần như là nơi endpoint bị bão hòa. Hãy khớp mức độ đồng thời cao nhất của bạn với lưu lượng truy cập thực tế dự kiến thay vì chọn một con số tròn lớn.
Tại sao các yêu cầu thất bại của tôi lại cao trong khi API vẫn hoạt động tốt?
ab gắn cờ một yêu cầu là thất bại nếu độ dài phản hồi khác nhau giữa các yêu cầu, điều này là bình thường đối với JSON động. Thêm cờ -l để ngừng đếm sự khác biệt về độ dài là thất bại. Sau đó, kiểm tra dòng "Non-2xx responses" để xem liệu có lỗi thực sự bên dưới không.
ab có thể kiểm thử một endpoint cần mã thông báo đăng nhập không?
Có, nếu bạn đã có một mã thông báo. Hãy truyền nó với -H "Authorization: Bearer YOUR_TOKEN". Điều mà ab không thể làm là đăng nhập trước để lấy một mã thông báo mới, sau đó sử dụng nó. Đó là một luồng nhiều bước, và bạn cần một công cụ dựa trên kịch bản như Apidog cho việc đó.
ab có hỗ trợ HTTP/2 không?
Không. ab sử dụng HTTP/1.x và, theo tài liệu chính thức, thậm chí còn không triển khai đầy đủ. Nếu hành vi của máy chủ của bạn dưới HTTP/2 quan trọng, hãy sử dụng một công cụ kiểm thử tải có hỗ trợ HTTP/2 thay thế.
