Rate Limiting — mấy thuật toán mà backend dev nào cũng gặp
Rate Limiting — mấy thuật toán mà backend dev nào cũng gặp
Có lần mình ngồi debug cái API, tự nhiên thấy toàn bộ request từ một user đều bị từ chối 429. Cái response chỉ vỏn vẹn "Too Many Requests". Lúc đó mình mới để ý — à, rate limiting. Cái khái niệm tưởng đơn giản nhưng khi đi sâu mới thấy có cả một thế giới thuật toán đằng sau.
Hồi mới học, mình cứ nghĩ rate limiting chỉ là "đếm số request rồi chặn khi vượt quá". Nhưng làm backend lâu rồi mới thấy, chọn sai thuật toán là user kêu, server chết, cái gì cũng tệ hết.
Ảnh: ThisIsEngineering — Pexels
Token Bucket — dễ hiểu nhất
Cơ chế như một cái xô đựng token. Mỗi request lấy 1 token ra khỏi xô. Token được bỏ vào xô đều đặn theo thời gian — ví dụ 10 token mỗi giây. Nếu xô hết token, request bị từ chối. Giống như mình có 10 cơ hội làm việc mỗi giây vậy. Thuật toán này rất phổ biến, dùng trong API Gateway, rate limiter của nhiều framework.
Leaky Bucket — ổn định hơn
Khác một chút: request vô được xếp hàng chờ xử lý, xử lý với tốc độ cố định. Nếu hàng chờ đầy thì request mới bị rớt. Giống như cái phễu nước — nước đổ vô bao nhiêu cũng được, nhưng chảy ra với tốc độ nhất định. Dùng tốt cho những hệ thống cần smoothing traffic, tránh đột biến.
Fixed Window — đơn giản nhất
Chia thời gian thành từng đoạn (VD: mỗi phút). Trong mỗi đoạn, đếm số request. Khi đạt ngưỡng thì chặn tới hết đoạn đó. Có một cái bẫy kinh điển: nếu user gửi 100 request ở giây cuối của phút A và 100 request ở giây đầu của phút B, thực tế họ gửi 200 request trong 2 giây — nhưng hệ thống vẫn cho qua vì mỗi phút riêng lẻ đều dưới ngưỡng.
Sliding Window — khắc phục bẫy Fixed Window
Thay vì reset đếm mỗi phút, Sliding Window nhìn vào một khoảng thời gian trượt. Dùng Redis Sorted Set với timestamp làm score — request nào nằm trong cửa sổ (VD: 60 giây trước) mới được tính. Chính xác hơn, nhưng tốn bộ nhớ hơn một chút.
Ảnh: Kevin Ku — Pexels
Nói chung, tuỳ bài toán mà chọn. Token Bucket dùng cho API public. Leaky Bucket cho traffic smoothing. Fixed Window cho đơn giản, Sliding Window cho chính xác. Mỗi cái đều có chỗ đứng riêng.
Mấy bạn có hay configure rate limiter cho project của mình hông? Hay cứ để mặc định framework là xong? Mình tò mò lắm.