Bạn đã bao giờ được yêu cầu nói chậm lại khi bạn đang nói quá nhanh không? Bộ giới hạn tốc độ API hoạt động tương tự cho các chương trình máy tính.
Một bộ giới hạn tốc độ API kiểm soát tần suất người dùng có thể gửi yêu cầu đến một dịch vụ. Nó giống như một cảnh sát giao thông cho dữ liệu, đảm bảo không ai chiếm dụng tất cả tài nguyên.
class InMemoryRateLimiter
MAX_REQUESTS = 100
WINDOW_SIZE = 3600 # 1 hour in seconds
def initialize
@requests = {}
end
def allow_request?(user_id)
current_time = Time.now.to_i
@requests[user_id] ||= []
@requests[user_id].reject! { |timestamp| timestamp < current_time - WINDOW_SIZE }
if @requests[user_id].size < MAX_REQUESTS
@requests[user_id] << current_time
true
else
false
end
end
end
# In your controller:
def index
limiter = InMemoryRateLimiter.new
if limiter.allow_request?(current_user.id)
# Process the request
else
render json: { error: "Too many requests" }, status: :too_many_requests
end
end
Ưu điểm: Cực kỳ nhanh, đơn giản để triển khai
Nhược điểm: Không lưu trữ lâu dài, không mở rộng được trên nhiều máy chủ
Có nhiều phương pháp khác để thực hiện giới hạn tốc độ mà không sử dụng lưu trữ trong bộ nhớ. Dưới đây là một số phương pháp thay thế:
Mỗi phương pháp này đều có ưu và nhược điểm riêng:
Redis xuất sắc trong các tình huống yêu cầu hiệu suất cao và hệ thống phân tán, khiến nó trở thành lựa chọn phổ biến cho việc giới hạn tốc độ trong môi trường sản xuất, mặc dù có thêm độ phức tạp trong việc quản lý máy chủ Redis.
class RedisRateLimiter
MAX_REQUESTS = 100
WINDOW_SIZE = 3600 # 1 hour in seconds
def initialize(user_id)
@user_id = user_id
@redis = Redis.new
end
def allow_request?
current_time = Time.now.to_i
key = "rate_limit:#{@user_id}"
# Removes all elements in the sorted set with a score between min and max (inclusive).
# We use it to remove all entries older than our time window (1 hour ago).
# This effectively "slides" our window, keeping only recent entries.
@redis.zremrangebyscore(key, 0, current_time - WINDOW_SIZE)
# Returns the number of elements in the sorted set.
# We use this to count how many requests have been made in our current time window.
current_count = @redis.zcard(key)
if current_count < MAX_REQUESTS
# Adds one or more members to a sorted set, or updates the score if it already exists.
# Here, we're adding an entry with the current timestamp as the score.
# The value is a unique string (timestamp plus random hex) to avoid collisions.
@redis.zadd(key, current_time, "#{current_time}.#{SecureRandom.hex(6)}")
@redis.expire(key, WINDOW_SIZE)
true
else
false
end
end
end
Lựa chọn tốt nhất phụ thuộc vào nhu cầu cụ thể của bạn, như yêu cầu về hiệu suất, nhu cầu lưu trữ lâu dài và quy mô của ứng dụng của bạn.
Các khái niệm và chiến lược giới hạn tốc độ mà chúng ta đã thảo luận có thể được áp dụng trên nhiều ngôn ngữ lập trình và framework khác nhau. Chúng không giới hạn ở Ruby hoặc Rails, mà có thể được điều chỉnh để phù hợp với bất kỳ stack công nghệ nào bạn đang làm việc.
Đối với các nhà phát triển Ruby, có một số gem có sẵn triển khai các khái niệm giới hạn tốc độ này, giúp bạn tiết kiệm công sức viết mọi thứ từ đầu. Một số gem phổ biến bao gồm:
Để sử dụng một trong những gem này, bạn thường thêm nó vào Gemfile của bạn và cấu hình nó theo nhu cầu của bạn.
Hãy nhớ rằng, mặc dù những gem này làm cho việc triển khai dễ dàng hơn trong Ruby, nhưng các nguyên tắc cơ bản vẫn giống nhau trên các ngôn ngữ khác. Cho dù bạn đang sử dụng Python, JavaScript, Java hay bất kỳ ngôn ngữ nào khác, bạn có thể áp dụng các chiến lược giới hạn tốc độ này bằng cách sử dụng các thư viện dành riêng cho ngôn ngữ hoặc tự triển khai logic.
Khóa chặt API của bạn: Các biện pháp bảo mật đơn giản (Whitelisting, JSON Web Tokens, API Keys, OAuth 2.0, Basic Authentication, Hash-based Message Authentication Code) https://vulehuan.com/vi/blog/2024/7/khoa-chat-api-cua-ban-cac-bien-phap-bao-mat-don-gian-whitelisting-json-web-tokens-api-keys-oauth-2-0-basic-authentication-hashbased-message-authentication-code-668a4357f0915ca45912b919.html