Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Các loại Performance Test — Load, Stress, Spike, Soak

Performance Testing with JMeter and k6 Bài 5/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn được giao nhiệm vụ "kiểm thử hiệu năng" cho một website bán hàng. Bạn mở JMeter lên, bắn 1.000 người dùng ảo vào trang chủ, thấy hệ thống không sập, và tự tin báo cáo: "Hệ thống ổn, chịu được tải." Ba tuần sau, đúng đợt sale 12.12, website chết cứng trong 8 phút đầu tiên và công ty mất hàng trăm triệu doanh thu.

Vấn đề không nằm ở công cụ, cũng không nằm ở việc bạn "test chưa đủ nhiều". Vấn đề là bạn đã chạy nhầm loại performance test. Bắn 1.000 user vào và giữ ổn định là một bài Load Test — nó chỉ trả lời câu hỏi "hệ thống có chạy tốt ở mức tải bình thường không". Nó hoàn toàn không trả lời được câu hỏi "chuyện gì xảy ra khi 20.000 người cùng bấm nút mua trong 30 giây" — đó là câu hỏi của một bài Spike Test.

Đây chính là lý do bài học này cực kỳ quan trọng. Performance testing không phải là một hoạt động đơn khối. Nó là một họ các loại test, mỗi loại có hình dạng tải (load pattern) khác nhau, trả lời một câu hỏi kinh doanh khác nhau. Chọn sai loại test cũng giống như dùng nhiệt kế để đo cân nặng — công cụ tốt, nhưng đo nhầm thứ.

Trong bài này, chúng ta sẽ đi qua 6 loại performance test kinh điển: Load, Stress, Spike, Soak (Endurance), Volume và Scalability. Bạn sẽ không chỉ học định nghĩa mà còn học cách nhìn ra: với một hệ thống cụ thể, đứng trước một nỗi lo cụ thể của doanh nghiệp, thì bạn nên chọn loại test nào. Đó là kỹ năng phân biệt cốt lõi của một Performance Engineer thực thụ.

Khái niệm cốt lõi

Điểm mấu chốt để hiểu và phân biệt các loại test là nhìn vào hình dạng đồ thị tải theo thời gian — trục hoành là thời gian, trục tung là số lượng người dùng ảo (virtual users) hoặc số request mỗi giây (requests per second). Mỗi loại test có một "chữ ký" hình học riêng.

1. Load Test — kiểm chứng ở mức tải dự kiến

Load Test tăng tải dần lên đến mức tải dự kiến trong thực tế (ví dụ tải giờ cao điểm), rồi giữ ổn định (hold/steady state) ở mức đó trong một khoảng thời gian đủ dài (thường 30–60 phút), sau đó giảm dần. Hình dạng đồ thị giống một cái "bàn ăn" — dốc lên, mặt phẳng, dốc xuống.

Mục đích: xác nhận rằng dưới tải bình thường mà bạn kỳ vọng, hệ thống đáp ứng các tiêu chí về thời gian phản hồi, throughput và tỉ lệ lỗi. Đây là loại test bạn chạy thường xuyên nhất, là "bài kiểm tra sức khỏe định kỳ" của hệ thống.

Câu hỏi nó trả lời: "Với 5.000 người dùng đồng thời như một ngày thường, trang thanh toán có phản hồi dưới 2 giây và tỉ lệ lỗi dưới 1% không?"

2. Stress Test — tìm điểm gãy

Stress Test tăng tải liên tục vượt qua mức bình thường, đẩy đến khi hệ thống bắt đầu suy giảm nghiêm trọng hoặc gãy hẳn. Đồ thị là một đường dốc lên đều, không có mặt phẳng ổn định — bạn cứ đổ thêm tải cho đến khi thấy khói.

Mục đích: tìm ra breaking point — ngưỡng mà tại đó hệ thống sụp đổ, và quan trọng hơn: quan sát hệ thống gãy như thế nàohồi phục ra sao khi tải giảm xuống. Một hệ thống tốt sẽ suy giảm "duyên dáng" (graceful degradation): làm chậm lại, trả lỗi có kiểm soát, rồi tự phục hồi khi tải giảm. Một hệ thống tồi sẽ sập cứng và không tự dậy được kể cả khi không còn ai truy cập.

Câu hỏi nó trả lời: "Hệ thống chịu được tối đa bao nhiêu trước khi gãy, và khi gãy thì nó gãy sạch sẽ hay để lại dữ liệu hỏng?"

3. Spike Test — cú sốc đột ngột

Spike Test đẩy một lượng tải cực lớn trong thời gian cực ngắn rồi rút đi đột ngột. Đồ thị là một cây kim nhọn hoắt — từ mức nền thấp vọt lên đỉnh trong vài giây, rồi rơi xuống. Điểm khác biệt so với Stress Test là tốc độ tăng tải: Stress tăng từ từ, Spike tăng gần như tức thời.

Mục đích: mô phỏng các sự kiện gây tải đột biến — mở bán vé concert, flash sale, một bài báo viral dẫn traffic về, hoặc chương trình khuyến mãi kích hoạt lúc 0h. Test này kiểm tra khả năng auto-scaling phản ứng kịp không, connection pool có bị cạn không, hàng đợi có tràn không.

Câu hỏi nó trả lời: "Khi 20.000 người cùng ập vào trong 30 giây lúc 0h ngày sale, hệ thống co giãn kịp hay sập?"

4. Soak Test (Endurance Test) — chạy đường dài

Soak Test giữ tải ở mức bình thường hoặc hơi trên bình thường nhưng kéo dài trong nhiều giờ, thậm chí nhiều ngày. Đồ thị nhìn giống Load Test nhưng mặt phẳng ổn định dài gấp hàng chục lần.

Mục đích: phát hiện các vấn đề chỉ lộ ra theo thời gian — memory leak (rò rỉ bộ nhớ khiến RAM tăng dần cho đến khi hết), connection leak, dung lượng đĩa log tăng không kiểm soát, kết nối database không được đóng đúng, cache phình to vô hạn. Những lỗi này vô hình trong một bài test 30 phút nhưng sẽ giết hệ thống sau 3 ngày chạy production.

Câu hỏi nó trả lời: "Nếu hệ thống chạy liên tục 72 giờ dưới tải thật, bộ nhớ có tăng đều đặn đến mức tràn không?"

5. Volume Test — thử với khối lượng dữ liệu lớn

Volume Test tập trung vào lượng dữ liệu thay vì lượng người dùng. Bạn nạp vào database một khối lượng dữ liệu khổng lồ (hàng chục triệu bản ghi) rồi đo hiệu năng. Nhiều truy vấn chạy nhanh như chớp với 10.000 bản ghi nhưng chậm như rùa với 50 triệu bản ghi vì thiếu index hoặc query kém tối ưu.

Câu hỏi nó trả lời: "Sau 2 năm vận hành với 40 triệu đơn hàng trong bảng, trang lịch sử giao dịch còn tải kịp không?"

6. Scalability Test — đo khả năng mở rộng

Scalability Test đo xem hiệu năng thay đổi thế nào khi bạn thêm tài nguyên (thêm server, thêm CPU/RAM). Mục tiêu là kiểm chứng: nếu tăng gấp đôi số server, throughput có tăng gần gấp đôi không, hay chỉ tăng thêm 20% vì có nút thắt cổ chai không mở rộng được (ví dụ một database duy nhất). Test này giúp bạn lập kế hoạch năng lực (capacity planning) và tính toán chi phí hạ tầng.

Câu hỏi nó trả lời: "Nếu tôi thêm 4 web server nữa, hệ thống có phục vụ được gấp đôi lượng người dùng không?"

Tình huống thực tế

Tình huống 1 — Tiki và bài học Spike Test bị bỏ quên

Một sàn thương mại điện tử lớn tại Việt Nam (tạm gọi theo mô hình của Tiki) chuẩn bị cho đợt "Siêu Sale 11.11". Đội QA đã chạy Load Test rất kỹ: mô phỏng 8.000 người dùng đồng thời — mức tải giờ cao điểm ngày thường — và giữ ổn định trong 1 giờ. Kết quả đẹp: thời gian phản hồi trung bình 1,3 giây, tỉ lệ lỗi 0,2%. Cả đội yên tâm.

Nhưng đúng 0h00 ngày 11.11, có tới 19.000 người dùng đổ vào trong vòng 40 giây đầu tiên để giành voucher giới hạn. Đây là một cú spike kinh điển, và nó khác hoàn toàn với 8.000 user tăng dần trong Load Test. Auto-scaling của họ được cấu hình phản ứng sau 90 giây quan sát metric — quá chậm cho một cú sốc 40 giây. Connection pool đến database cạn kiệt, request xếp hàng chờ, timeout dây chuyền, và trang chủ trả lỗi 503 trong 6 phút.

Diễn giải: Load Test đã pass hoàn hảo nhưng vô dụng cho kịch bản thực tế, vì nó đo nhầm hình dạng tải. Mức tải đỉnh (19.000) không phải vấn đề duy nhất — tốc độ đạt đỉnh mới là kẻ giết người. Một bài Spike Test sẽ phơi bày ngay việc auto-scaling phản ứng chậm và connection pool cấu hình quá nhỏ.

Bài học rút ra: Với bất kỳ sự kiện nào có yếu tố "mở cổng lúc 0h" hoặc "voucher giới hạn", Spike Test là bắt buộc, không phải tùy chọn. Load Test tốt không thay thế được Spike Test.

Tình huống 2 — Ứng dụng ví điện tử và con quái vật memory leak

Một startup fintech Đông Nam Á (mô hình tương tự các ví điện tử như MoMo hay ShopeePay) vận hành dịch vụ chuyển tiền. Họ chạy Load Test mỗi lần release: 30 phút, 3.000 giao dịch/phút, luôn xanh. Nhưng cứ khoảng 4–5 ngày sau mỗi lần deploy, một service backend lại tự khởi động lại giữa đêm, gây ra vài phút gián đoạn. Đội vận hành phải viết cron tự động restart service mỗi 3 ngày — một cách "chữa cháy" tồi tệ.

Một kỹ sư performance mới vào đề xuất chạy Soak Test: giữ tải 3.000 giao dịch/phút liên tục trong 48 giờ và theo dõi biểu đồ bộ nhớ. Kết quả rất rõ ràng: RAM của service tăng đều đặn khoảng 40 MB mỗi giờ và không bao giờ giảm. Truy vết ra nguyên nhân: mỗi giao dịch mở một kết nối tới một service bên thứ ba nhưng không đóng đúng cách trong nhánh xử lý lỗi. Sau khoảng 100 giờ, bộ nhớ đầy và JVM buộc phải restart.

Diễn giải: Lỗi này về mặt vật lý không thể xuất hiện trong bài Load Test 30 phút — 30 phút chỉ tích lũy khoảng 20 MB rò rỉ, nằm trong biên độ dao động bình thường và không ai để ý. Chỉ có yếu tố thời gian dài của Soak Test mới biến một vết rò nhỏ thành một tín hiệu rõ ràng trên đồ thị.

Bài học rút ra: Nếu hệ thống của bạn chạy 24/7, bạn bắt buộc phải có Soak Test định kỳ. Việc phải "restart định kỳ để cho chắc" gần như luôn là dấu hiệu của một memory leak chưa được Soak Test phát hiện.

Tình huống 3 — Nền tảng học trực tuyến và giới hạn Scalability

Một nền tảng học trực tuyến (bối cảnh tương tự chính Vietnamcos) đang tăng trưởng nhanh. Ban lãnh đạo hỏi một câu rất cụ thể: "Sang năm dự kiến lượng học viên tăng gấp 3, chúng ta cần mua thêm bao nhiêu server?" Đội kỹ thuật ban đầu định trả lời đơn giản "gấp 3 học viên thì thêm gấp 3 server", nhưng người phụ trách performance quyết định chạy một Scalability Test để có số liệu thật.

Họ đo throughput tối đa với lần lượt 2, 4 và 6 web server, giữ nguyên một database. Kết quả: từ 2 lên 4 server, throughput tăng từ 1.200 lên 2.100 request/giây (tốt, gần gấp đôi). Nhưng từ 4 lên 6 server, throughput chỉ nhích từ 2.100 lên 2.300 — thêm 50% server nhưng chỉ thêm 10% năng lực. Nguyên nhân: database đơn đã trở thành nút thắt cổ chai, thêm web server cũng vô ích.

Diễn giải: Nếu không có Scalability Test, công ty đã chi tiền mua thêm web server một cách lãng phí trong khi vấn đề thật nằm ở tầng database. Test này biến một quyết định đầu tư mơ hồ thành một con số có căn cứ: "Đừng thêm web server nữa, hãy đầu tư vào read replica cho database trước."

Bài học rút ra: Scalability Test là công cụ nối performance với quyết định kinh doanh và ngân sách. Mở rộng tuyến tính là điều phải chứng minh bằng số liệu, không phải giả định.

Hướng dẫn từng bước

Đây là quy trình để chọn và thiết kế đúng loại test cho một tình huống:

Bước 1 — Xác định câu hỏi kinh doanh trước, đừng chọn công cụ trước. Viết ra một câu duy nhất: bạn đang lo lắng điều gì? "Sale 12.12 có sập không" (→ Spike), "chạy 3 ngày có leak không" (→ Soak), "ngày thường có đủ nhanh không" (→ Load), "chịu tối đa bao nhiêu" (→ Stress).

Bước 2 — Chuyển câu hỏi thành hình dạng tải. Vẽ ra giấy đồ thị tải theo thời gian mà bạn cần: dốc lên rồi giữ (Load), dốc lên mãi (Stress), kim nhọn (Spike), hay mặt phẳng rất dài (Soak). Hình dạng này chính là bản thiết kế kịch bản.

Bước 3 — Định lượng các tham số. Xác định con số cụ thể: mức tải bình thường (baseline) là bao nhiêu user/giây? Mức đỉnh mục tiêu? Thời gian ramp-up (tăng dần)? Thời gian hold (giữ ổn định)? Với Load, hold thường 30–60 phút; với Soak, hold từ 8–72 giờ; với Spike, ramp-up chỉ vài giây.

Bước 4 — Định nghĩa tiêu chí đạt/trượt (pass/fail) trước khi chạy. Ví dụ: p95 latency < 2s, error rate < 1%, throughput ≥ 2.000 req/s, RAM không tăng quá 5% sau 24h. Không có tiêu chí thì kết quả test chỉ là "số liệu đẹp" vô nghĩa.

Bước 5 — Chuẩn bị dữ liệu và môi trường tương xứng. Đặc biệt với Volume Test, bạn phải nạp dữ liệu đủ lớn trước. Môi trường test nên gần production nhất có thể — test trên máy yếu rồi suy ra production là sai lầm phổ biến.

Bước 6 — Chạy, giám sát cả hai phía. Đừng chỉ nhìn số liệu từ phía công cụ tải (client-side: latency, throughput). Phải giám sát cả phía server (CPU, RAM, số kết nối DB, độ dài hàng đợi). Với Soak Test, đồ thị RAM theo thời gian là ngôi sao chính.

Bước 7 — So sánh với tiêu chí và ghi nhận cách hệ thống hồi phục. Đặc biệt với Stress và Spike: sau khi rút tải, hệ thống có tự trở lại bình thường không, mất bao lâu? Khả năng hồi phục quan trọng ngang với điểm gãy.

Lỗi thường gặp & mẹo

Lỗi 1: Chỉ chạy Load Test rồi tưởng đã "test hiệu năng xong". Đây là lỗi phổ biến nhất. Load Test chỉ trả lời một câu hỏi hẹp. Một chiến lược đầy đủ cần ít nhất Load + Stress + Soak, và thêm Spike nếu có sự kiện đột biến.

Lỗi 2: Nhầm Stress Test với Spike Test. Nhiều người nghĩ "bắn thật nhiều user vào" là như nhau. Không phải. Khác biệt nằm ở tốc độ tăng tải. Stress tăng từ từ để tìm ngưỡng gãy; Spike tăng tức thời để kiểm tra phản ứng với cú sốc. Cùng một đỉnh 20.000 user nhưng đạt tới trong 10 phút (Stress) hay 20 giây (Spike) sẽ phơi bày những lỗi hoàn toàn khác nhau.

Lỗi 3: Soak Test quá ngắn. Chạy Soak 1 giờ rồi kết luận "không leak" là vô nghĩa. Memory leak thường cần nhiều giờ để lộ ra trên đồ thị. Nguyên tắc: Soak Test tối thiểu 8 giờ, lý tưởng là qua đêm hoặc cuối tuần.

Lỗi 4: Không có baseline để so sánh. Nói "hệ thống chịu được 10.000 user" là vô nghĩa nếu không biết mức bình thường là bao nhiêu. Luôn thiết lập baseline (tải giờ cao điểm thực tế) trước, rồi các loại test khác mới có tham chiếu.

Lỗi 5: Quên đo khả năng hồi phục. Test không kết thúc ở lúc hệ thống gãy. Câu hỏi vàng của Stress/Spike là: "Khi tải rút đi, nó có tự đứng dậy không?" Rất nhiều hệ thống gãy rồi nằm luôn dù không còn ai truy cập.

Mẹo — nhớ nhanh bằng phép loại suy sức khỏe: Load Test giống khám sức khỏe định kỳ (mọi thứ bình thường có ổn không). Stress Test giống chạy trên máy chạy bộ tăng tốc đến kiệt sức (ngưỡng chịu đựng tối đa). Spike Test giống bị giật mình đột ngột (tim có loạn nhịp không). Soak Test giống chạy marathon (sức bền đường dài). Nhớ được bốn phép loại suy này là bạn không bao giờ nhầm nữa.

Bài tập thực hành

Bài 1 — Phân loại tình huống. Với mỗi tình huống dưới đây, hãy xác định loại test phù hợp nhất và giải thích tại sao (chỉ cần viết ra, chưa cần chạy công cụ):

  • (a) Grab muốn biết app đặt xe có ổn định trong giờ tan tầm 17h–19h ngày thường không.
  • (b) Một ngân hàng số lo lắng service internet banking tự restart mỗi vài ngày.
  • (c) Ban vé một concert lo lúc mở bán vé 0h sẽ có hàng chục nghìn người ập vào cùng lúc.
  • (d) CTO muốn biết hệ thống chịu được tối đa bao nhiêu user trước khi cần nâng cấp khẩn.
  • (e) Trang lịch sử đơn hàng ngày càng chậm sau 2 năm tích lũy dữ liệu.
Bài 2 — Vẽ đồ thị tải. Trên giấy, vẽ hình dạng đồ thị (user theo thời gian) cho bốn loại: Load, Stress, Spike, Soak. Ghi rõ trục thời gian với con số cụ thể (ví dụ Soak: hold 24 giờ; Spike: ramp-up 30 giây).

Bài 3 — Thiết kế tham số. Giả sử hệ thống của bạn có tải bình thường giờ cao điểm là 4.000 người dùng đồng thời. Hãy viết ra tham số cụ thể (mức tải đỉnh, thời gian ramp-up, thời gian hold, tiêu chí pass/fail) cho: một bài Load Test, một bài Spike Test cho sự kiện flash sale, và một bài Soak Test cuối tuần.

Bài 4 — Phản biện. Một đồng nghiệp nói: "Mình đã chạy Stress Test tới 50.000 user không sập, vậy khỏi cần Spike Test." Hãy viết 3–4 câu phản biện, chỉ ra lỗ hổng trong lập luận này.

(Gợi ý đáp án Bài 1: a→Load, b→Soak, c→Spike, d→Stress, e→Volume.)

Tóm tắt

Performance testing không phải một hoạt động đơn khối mà là một họ các loại test, mỗi loại có một hình dạng tải riêng và trả lời một câu hỏi kinh doanh riêng. Sáu loại cốt lõi cần nắm:

  • Load Test — tải dự kiến, giữ ổn định → kiểm chứng hệ thống ở mức bình thường (khám sức khỏe định kỳ).
  • Stress Test — tăng tải đến khi gãy → tìm điểm gãy và cách hệ thống suy giảm/hồi phục.
  • Spike Test — tải cực lớn trong thời gian cực ngắn → kiểm tra phản ứng với cú sốc đột ngột (sale 0h, mở bán vé).
  • Soak Test — tải bình thường kéo dài nhiều giờ/ngày → săn memory leak và các lỗi tích lũy theo thời gian.
  • Volume Test — khối lượng dữ liệu lớn → phát hiện truy vấn suy giảm khi dữ liệu phình to.
  • Scalability Test — thêm tài nguyên rồi đo → phục vụ capacity planning và quyết định đầu tư hạ tầng.
Nguyên tắc vàng: luôn bắt đầu từ câu hỏi kinh doanh, chuyển nó thành hình dạng tải, rồi mới chọn công cụ. Chọn đúng loại test quan trọng hơn nhiều so với việc chạy thật nhiều test. Ba bài học thực tế — cú spike làm sập sàn TMĐT, con memory leak ẩn trong ví điện tử, và giới hạn scalability ở tầng database — đều cho thấy cùng một điều: một bài Load Test đẹp không đảm bảo hệ thống an toàn, vì nó chỉ đo một góc nhỏ của bức tranh hiệu năng. Ở các bài sau, chúng ta sẽ bắt tay dựng từng kịch bản này bằng JMeter và k6.