# Kiểm Thử Hiệu Năng Web Với JMeter (Case Thực Tế)

> Học viên của tôi thường hỏi: học lý thuyết JMeter rồi, giờ làm một bài thật ra sao? 🙂 Bài này tôi đi trọn một case thực tế, từ đầu đến báo cáo. Kiểm thử hiệu năng web là việc dùng công cụ như JMeter m…

- **URL canonical**: https://itlearn.edu.vn/blog/kiem-thu-hieu-nang-jmeter
- **Published**: 2026-07-18T11:00:00+07:00
- **Modified**: 2026-07-18T21:04:27+07:00
- **Author**: Anh Tuấn
- **Category**: Performance test (https://itlearn.edu.vn/blog/cat/performance-test)
- **Reading time**: 13 phút
- **Source site**: IT LEARN — Học viện Software Testing tiếng Việt

---

Học viên của tôi thường hỏi: học lý thuyết JMeter rồi, giờ làm một bài thật ra sao? 🙂 Bài này tôi đi trọn một case thực tế, từ đầu đến báo cáo. **Kiểm thử hiệu năng web là việc dùng công cụ như JMeter mô phỏng nhiều người dùng ảo truy cập website đồng thời, rồi đo response time, throughput và error rate để xác định sức chịu tải và điểm nghẽn của hệ thống.**

![kiểm thử hiệu năng web bằng JMeter - Thread Group 100 user và Summary Report hiển thị response time, throughput, error rate](/uploads/2026/07/kiem-thu-hieu-nang-jmeter.jpg)

Tôi lấy ví dụ quen thuộc của series: "Hệ thống đặt phòng họp nội bộ", với kịch bản 100 nhân viên cùng đặt phòng vào đầu giờ sáng. Nếu bạn chưa rõ công cụ, hãy đọc [JMeter là gì](/blog/jmeter-la-gi) trước; còn muốn nắm nền lý thuyết thì xem [Performance testing là gì](/blog/performance-testing-la-gi).

## Bài toán: đo tải một website

Trước khi mở JMeter, phải chốt được *đo tải website* để làm gì. Trong case này, "Hệ thống đặt phòng họp nội bộ" hay bị chậm lúc 8h sáng khi cả công ty tranh nhau đặt phòng. Mục tiêu bài **test hiệu năng website** là trả lời ba câu: server chịu được bao nhiêu người cùng lúc, response time ở mức tải đó là bao nhiêu, và bắt đầu lỗi từ ngưỡng nào.

Một bài *performance test web* tử tế luôn bắt đầu bằng việc định nghĩa mục tiêu và ngưỡng chấp nhận (SLA) rõ ràng. Với hệ thống đặt phòng, tôi đặt tiêu chí:

Tiêu chí

Ngưỡng chấp nhận

Ý nghĩa

Tải mục tiêu

100 user đồng thời

Số nhân viên cao điểm đầu giờ

Response time (95% Line)

≤ 1.500 ms

95% request phải nhanh hơn mốc này

Throughput

≥ 50 request/giây

Sức xử lý tối thiểu chấp nhận được

Error rate

≤ 1%

Tỷ lệ request lỗi tối đa cho phép

Có bảng ngưỡng này, việc **kiểm thử hiệu năng web** không còn là "chạy cho vui" mà thành một phép kiểm PASS/FAIL rõ ràng. API mục tiêu tôi test là `POST /api/bookings` — đặt một phòng họp.

## Thiết lập kịch bản (số user, ramp-up)

Kịch bản tải nằm ở **Thread Group** — nơi khai báo số người dùng ảo. Với case 100 nhân viên, tôi tạo Thread Group (chuột phải Test Plan → *Add → Threads (Users) → Thread Group*) và điền ba thông số cốt lõi:

- **Number of Threads (users):** `100` — mô phỏng 100 nhân viên.

- **Ramp-up period (seconds):** `20` — JMeter thả dần 100 luồng trong 20 giây, tức mỗi 0,2 giây thêm một người dùng. Thả từ từ để mô phỏng người dùng đến rải rác, tránh dồn 100 request vào đúng một mili-giây (không thực tế).

- **Loop Count:** `5` — mỗi luồng lặp 5 lần, tổng 500 request.

Ramp-up là thông số người mới hay đặt sai nhất. Đặt ramp-up = 0 nghĩa là bắn cả 100 người cùng một khoảnh khắc — tạo cú sốc giả tạo mà đời thực hiếm khi xảy ra. Ngược lại, ramp-up quá dài (vd 600 giây) thì tại một thời điểm chỉ có vài người đang hoạt động, không bao giờ đạt tải mục tiêu 100 đồng thời. Công thức tôi hay dùng: ramp-up (giây) ≈ số user chia cho tốc độ user đến mỗi giây mà bạn muốn mô phỏng.

Nếu mục tiêu là giữ tải ổn định trong một khoảng thời gian, hãy dùng thêm ô **Scheduler** hoặc plugin *Ultimate Thread Group*. Muốn hiểu vì sao 100 user "đều đều" khác hẳn kịch bản dồn tải đột ngột, đọc thêm [load test vs stress test](/blog/load-test-vs-stress-test).

## Ghi & tham số hóa request

Nếu API chỉ có một request thì gõ tay là xong, nhưng luồng đặt phòng thật gồm nhiều bước: đăng nhập → xem phòng trống → đặt phòng. Lúc này có hai kỹ thuật cần nắm cho một bài **jmeter web test** đúng nghĩa.

**Ghi kịch bản (recording).** Thay vì dựng tay từng request, bạn dùng **HTTP(S) Test Script Recorder**: JMeter đóng vai proxy, bạn thao tác trên trình duyệt và nó tự ghi lại toàn bộ request thành các HTTP Request Sampler. Cách này tiết kiệm thời gian với luồng dài, sau đó bạn dọn bớt request thừa (ảnh, CSS, tracking).

**Tham số hóa (parameterization).** Đây là điểm sống còn: nếu cả 100 luồng cùng đăng nhập một tài khoản và đặt cùng một phòng, kết quả không phản ánh thực tế (cache che mất tải, hoặc trùng dữ liệu gây lỗi giả). Giải pháp là **CSV Data Set Config**:

- Tạo file `users.csv` chứa dữ liệu thật, mỗi dòng một bộ, ví dụ `username,password,roomId`.

- Thêm *Config Element → CSV Data Set Config*, trỏ tới file và khai báo tên biến `username,password,roomId`.

- Trong HTTP Request, tham chiếu biến bằng cú pháp `${username}`, `${roomId}` — mỗi luồng sẽ đọc một dòng khác nhau.

Ngoài ra, với luồng có token, bạn dùng **JSON Extractor** để bắt token từ response đăng nhập rồi tái sử dụng ở request đặt phòng — giống cách xử lý biến khi test API thủ công. Đừng quên thêm **Response Assertion** để kiểm tra response chứa đúng dữ liệu (vd `"status":"confirmed"`), và **Duration Assertion** để đánh dấu FAIL nếu một request vượt ngưỡng thời gian. Nhanh mà trả sai thì con số đẹp cũng vô nghĩa.

## Chạy test & đọc report (response time, error %)

Dựng xong, tôi **không** chạy tải thật bằng giao diện đồ họa (GUI) — GUI ngốn RAM và làm sai lệch số liệu. Cách chuẩn là chạy chế độ non-GUI bằng dòng lệnh:

`bash
jmeter -n -t booking.jmx -l ketqua.jtl -e -o report/`

Trong đó `-n` là non-GUI, `-t` trỏ file kịch bản `.jmx`, `-l` ghi kết quả thô ra `.jtl`, còn `-e -o report/` sinh sẵn một **HTML dashboard report** trực quan sau khi chạy. Khi debug kịch bản thì vẫn mở GUI với **Summary Report** hoặc **Aggregate Report** cho nhanh mắt.

Đọc report mới là phần quyết định. Bảng dưới là các chỉ số cốt lõi của một bài **kiểm thử hiệu năng web** và cách diễn giải:

Chỉ số

Ý nghĩa

Cách đọc

**Samples**

Tổng request đã gửi

Đối chiếu với 500 kỳ vọng (100×5)

**Average**

Response time trung bình (ms)

Tham khảo, nhưng dễ bị che bởi ngoại lệ

**90% / 95% Line**

90–95% request nhanh hơn mốc này

Chỉ số chính để so với SLA

**Throughput**

Số request/giây server xử lý

Càng cao càng khỏe; so với ngưỡng ≥50/s

**Error %**

Tỷ lệ request lỗi (không phải 2xx)

Vượt 1% là báo động

Nguyên tắc vàng: **đừng chỉ nhìn Average.** Ví dụ trong lần chạy đầu, hệ thống đặt phòng cho Average = 480 ms nghe êm tai, nhưng 95% Line = 4.200 ms và Error % = 6% — nghĩa là phần đông người dùng vẫn phải chờ hơn 4 giây và cứ 16 người thì có 1 người gặp lỗi. Con số Average đã "trung bình hóa" che mất sự thật. Luôn nhìn **percentile (95% Line)** và **Error %** trước tiên.

## Phân tích nghẽn & báo cáo

Có số xấu rồi, việc tiếp theo là tìm *nghẽn ở đâu* — đây mới là giá trị thật của **performance test web**. Error % cao và percentile tăng vọt chỉ là triệu chứng; nguyên nhân thường nằm ở tầng dưới. Quy trình khoanh vùng tôi hay áp dụng:

- **Đọc loại lỗi trong .jtl:** lỗi `500` là server sập/exception, `503` là quá tải, `Connection timeout` là server không kịp nhận kết nối. Mỗi mã chỉ về một tầng khác nhau.

- **Xem đường cong theo tải:** trong HTML dashboard, nhìn biểu đồ *Response Time Over Time*. Nếu response time tăng tuyến tính theo số user rồi "gãy" tại một mốc (vd 70 user), đó chính là ngưỡng bão hòa.

- **Đối chiếu tài nguyên server:** song song với JMeter, theo dõi CPU, RAM và database ở phía server (dùng công cụ giám sát). CPU chạm 100% hay connection pool database cạn thường là thủ phạm phổ biến nhất của nghẽn.

Bảng đối chiếu triệu chứng — nguyên nhân giúp bạn đọc nhanh:

Triệu chứng quan sát

Nghi vấn nghẽn

Hướng xử lý gợi ý

Response time tăng vọt sau ngưỡng X user

Server bão hòa CPU/RAM

Tối ưu code, tăng tài nguyên

Nhiều lỗi 503 / timeout

Web server hết luồng xử lý

Chỉnh thread pool, thêm instance

Chậm ở request có truy vấn DB

Nghẽn database, thiếu index

Tối ưu query, thêm index/cache

Throughput không tăng dù thêm user

Đã chạm trần một tài nguyên

Xác định tài nguyên giới hạn

Cuối cùng là **báo cáo**. Một report tốt không dừng ở ảnh chụp Summary. Nó nêu rõ: mục tiêu và ngưỡng SLA ban đầu, cấu hình test (100 user, ramp-up 20s, 5 vòng), kết quả đo (95% Line, throughput, error %), kết luận PASS/FAIL so với SLA, và điểm nghẽn tìm được kèm đề xuất. Đây chính là bộ kỹ năng được luyện sâu trong [khóa Performance JMeter](/performance.html) của IT LEARN, trên dự án thật.

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

### Đo tải website bằng gì?

Phổ biến nhất là Apache JMeter — công cụ mã nguồn mở miễn phí, mô phỏng hàng trăm người dùng ảo gửi request đồng thời rồi đo response time, throughput và error rate. Ngoài JMeter còn có k6, Gatling hay Locust, nhưng JMeter dễ học nhất cho người mới nhờ giao diện đồ họa và cộng đồng lớn.

### Ramp-up trong JMeter là gì?

Ramp-up period là thời gian JMeter dùng để khởi động dần tất cả các luồng (người dùng ảo). Ví dụ 100 user với ramp-up 20 giây thì cứ 0,2 giây thêm một người dùng. Nó giúp mô phỏng người dùng đến rải rác thay vì dồn cục một khoảnh khắc, cho kết quả tải sát thực tế hơn nhiều.

### Bao nhiêu user là đủ để test?

Không có con số cố định — nó bằng lượng người dùng đồng thời thật ở giờ cao điểm cộng một biên an toàn. Hãy lấy số liệu thực từ analytics hoặc log, ví dụ hệ thống đặt phòng cao điểm 100 người thì test 100 và tăng dần lên 150–200 để tìm ngưỡng gãy, thay vì đoán mò.

### Đọc report JMeter thế nào?

Đừng chỉ nhìn Average vì nó dễ bị ngoại lệ che mất. Ưu tiên đọc 95% Line (percentile), Throughput và Error % trước. Đối chiếu chúng với ngưỡng SLA đã đặt: nếu 95% Line vượt mốc chấp nhận hoặc Error % trên 1% là hệ thống đang có vấn đề dưới tải, cần phân tích nghẽn.

### Khi nào website bị nghẽn?

Website bị nghẽn khi response time tăng vọt và error rate leo lên lúc số người dùng đồng thời vượt sức chịu của một tài nguyên nào đó. Dấu hiệu thường thấy là throughput ngừng tăng dù thêm user, xuất hiện lỗi 503 hoặc timeout, CPU/RAM server chạm trần, hoặc connection pool database cạn kiệt. Muốn thực hành trọn một dự án kiểm thử hiệu năng web từ dựng kịch bản đến phân tích nghẽn và báo cáo, bạn có thể tham khảo [khóa Performance JMeter](/performance.html) của IT LEARN.

