Bối cảnh: Tại sao hệ thống của bạn “ngỏm” khi khách hàng vừa kéo đến?
Cảm giác server “sập nguồn” ngay lúc chạy campaign là nỗi ám ảnh của mọi lập trình viên. Code chạy mượt ở local hay staging với vài ba user chẳng nói lên điều gì. Khi lượng truy cập thực tế tăng vọt, lỗi 502 xuất hiện, database treo cứng, và khách hàng bắt đầu rời đi. Đó là cái giá phải trả khi chúng ta bỏ qua Performance Testing.
Hệ thống có thể chạy đúng, nhưng liệu nó có chạy nhanh khi 1.000 hay 10.000 người cùng lúc nhấn nút “Mua hàng”? Trước đây, mình thường dùng JMeter. Nó mạnh nhưng file cấu hình XML cực kỳ cồng kềnh và khó tùy biến. Locust thì khác. Nó cho phép viết kịch bản test bằng Python thuần túy. Bạn có thể dùng mọi thư viện, viết vòng lặp hay xử lý logic như đang code một tính năng thực thụ.
Trong một dự án web app với 5 developer, mình đã áp dụng Locust ngay từ giai đoạn phát triển. Kết quả thật bất ngờ. Team phát hiện một đoạn query SQL thiếu Index khiến thời gian phản hồi tăng từ 50ms lên tận 5 giây khi có trên 200 user đồng thời. Nếu đợi đến lúc Go-live mới biết thì chắc chắn là thảm họa.
Cài đặt Locust trên môi trường Python
Máy bạn chỉ cần cài sẵn Python 3.7 trở lên. Việc cài đặt Locust cực kỳ nhanh gọn qua pip:
pip install locust
Sau khi cài xong, hãy kiểm tra phiên bản bằng lệnh:
locust -V
Nếu terminal trả về thông tin phiên bản (ví dụ: locust 2.15.1), bạn đã sẵn sàng để bắt đầu.
Xây dựng kịch bản Load Test chi tiết với Python
Với Locust, kịch bản test là một file Python (thường là locustfile.py). Dưới đây là ví dụ thực tế để kiểm tra một trang web bán hàng.
import time
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
# Giả lập thời gian chờ giữa các thao tác (1-5 giây)
wait_time = between(1, 5)
@task(3)
def view_homepage(self):
"""Người dùng xem trang chủ"""
self.client.get("/")
@task(1)
def view_product_detail(self):
"""Người dùng xem chi tiết sản phẩm"""
self.client.get("/product/123", name="/product/[id]")
@task(2)
def post_comment(self):
"""Người dùng đăng bình luận"""
self.client.post("/api/comment", json={
"user": "test_user",
"content": "Sản phẩm rất tuyệt!"
})
Bóc tách mã nguồn:
- HttpUser: Đại diện cho một “con bot”. Mỗi user sẽ sở hữu một session riêng biệt như người dùng thật.
- wait_time: Rất quan trọng. Người dùng thực tế cần thời gian đọc nội dung trước khi click tiếp, không ai nhấn 100 lần/giây cả.
- @task(weight): Con số trong ngoặc là trọng số. Ở ví dụ trên, xác suất người dùng vào trang chủ cao gấp 3 lần việc đăng bình luận.
- self.client: Cách dùng tương tự thư viện
requestsphổ biến để gửi GET, POST, PUT.
Chạy kiểm thử và đọc chỉ số Dashboard
Để bắt đầu cuộc “tấn công” giả lập, hãy mở Terminal và gõ:
locust -f locustfile.py
Truy cập http://localhost:8089 để vào giao diện quản lý. Tại đây, bạn cần nhập 3 thông số:
- Number of users: Tổng số user muốn giả lập (ví dụ: 1000).
- Spawn rate: Tốc độ tạo user mới mỗi giây (ví dụ: 10).
- Host: URL hệ thống cần test.
Đừng bỏ qua các chỉ số sống còn này:
Khi biểu đồ bắt đầu chạy, đừng chỉ nhìn vào số lượng Request. Hãy tập trung vào:
- RPS (Requests Per Second): Số yêu cầu xử lý được mỗi giây. Nếu RPS đi ngang trong khi User vẫn tăng, hệ thống đã chạm ngưỡng.
- Response Time (p95): Đây là chỉ số then chốt. Nó cho biết 95% người dùng nhận phản hồi dưới mức thời gian này. Nếu p95 vượt quá 2 giây, khách hàng sẽ cảm thấy khó chịu.
- Failures: Tỷ lệ lỗi. Nếu thấy lỗi 5xx, hãy check ngay log để xem Database có bị tràn Connection Pool hay không.
Kinh nghiệm thực tế: Khi nào cần chạy Distributed?
Một máy tính cá nhân thường chỉ giả lập được khoảng 1.000 user. Để test hệ thống chịu tải hàng vạn người dùng (ví dụ 50.000 CCU), một máy đơn lẻ sẽ bị nghẽn CPU trước cả server. Bí kíp ở đây là dùng chế độ Master-Worker.
Bạn dựng 1 máy Master điều khiển và nhiều máy Worker để nã request. Thực tế khi Stress Test cho một hệ thống Fintech, mình đã dùng tới 20 Worker trên AWS để giả lập 100.000 người truy cập trong 15 phút. Nhờ vậy, team phát hiện Redis bị tràn bộ nhớ do lưu Cache quá tay – một lỗi cực khó thấy ở quy mô nhỏ.
# Trên máy Master
locust -f locustfile.py --master
# Trên các máy Worker
locust -f locustfile.py --worker --master-host=<IP_MASTER>
Locust không chỉ giúp bạn yên tâm khi deploy mà còn giúp bạn hiểu rõ giới hạn hạ tầng. Đừng đợi khách hàng phàn nàn. Hãy tự “đánh sập” hệ thống của mình một cách có kiểm soát để xây dựng nó vững chắc hơn.

