Rate Limiting: Tại sao API của bạn cần nó và chọn thuật toán nào?
Khi hệ thống mở rộng, việc giới hạn tốc độ truy cập trở thành vấn đề sống còn. Cùng bàn về Token Bucket, Leaky Bucket và cách triển khai thực tế.
Nguyễn Văn A Nguồn
Cách đây một năm, team tôi từng gặp sự cố sập database chỉ vì một… con bot scrape dữ liệu. Nó gửi request liên tục vào API search, và vì API đó query khá nặng, DB server bị quá tải (CPU 100%) khiến người dùng thật không thể truy cập được.
Đó là lúc chúng tôi nhận ra tầm quan trọng của Rate Limiting. Không chỉ để chống DDOS, mà còn để đảm bảo sự công bằng (Fairness) cho mọi người dùng và bảo vệ hạ tầng khỏi những “tai nạn” không đáng có.
Có nhiều cách để giới hạn request, nhưng phổ biến nhất là hai thuật toán: Token Bucket và Leaky Bucket.
Token Bucket (Xô Token)
Hãy hình dung bạn có một cái xô, và server liên tục thả vào đó các đồng xu (token) theo một tốc độ cố định (ví dụ: 10 xu/giây). Xô có dung tích giới hạn. Khi người dùng gọi API, họ phải lấy một đồng xu ra. Nếu xô rỗng, request bị từ chối.
Cơ chế này rất linh hoạt vì nó cho phép Burst (đột biến). Ví dụ người dùng có thể im lặng 10 giây để tích lũy 100 token, sau đó “xả” 100 request cùng lúc. Điều này phù hợp với hành vi lướt web tự nhiên của con người. AWS và Stripe dùng thuật toán này rất nhiều.
Leaky Bucket (Xô Rò Rỉ)
Ngược lại, Leaky Bucket giống như cái phễu. Request đổ vào miệng phễu ồ ạt thế nào không biết, nhưng ở đầu ra (phía server xử lý), request luôn chảy nhỏ giọt đều đặn từng cái một.
Cơ chế này tốt nếu bạn muốn bảo vệ database tuyệt đối. Server sẽ luôn chịu tải ổn định, không bao giờ bị shock. Tuy nhiên, trải nghiệm người dùng có thể bị ảnh hưởng nếu họ cần thao tác nhanh mà bị ép phải xếp hàng.
Triển khai thực tế
Để triển khai, đừng cố tự viết logic đếm request bằng SQL Database (như MySQL), nó sẽ chết trước cả API của bạn vì lock table. Hãy dùng Redis.
Redis cực nhanh và hỗ trợ atomic operation (INCR, EXPIRE). Một mô hình đơn giản là dùng key rate_limit:{user_id} và set thời gian hết hạn cho nó.
Nếu hệ thống lớn hơn, hãy cân nhắc đặt Rate Limit ngay tại tầng API Gateway (như Kong, Nginx, hoặc AWS API Gateway) thay vì xử lý trong code (Application Layer). Chặn request rác càng sớm thì server càng rảnh tay để làm việc có ích.
Thuật toán nào cho phép 'burst' (đột biến) lượng request trong thời gian ngắn?
Thử Thách Kiến Thức Lịch Sử?
Khám phá hàng trăm câu hỏi trắc nghiệm lịch sử thú vị tại HistoQuiz. Vừa học vừa chơi, nâng cao kiến thức ngay hôm nay!
System Design Primer
Nhà xuất bản gốcBài viết này được trích dẫn và tổng hợp từ System Design Primer, nơi cung cấp các bài viết và tài liệu chất lượng cao.