1. Basic concepts of API rate limiting
API Rate Limiting is a mechanism that controls the request rate of users accessing the API, preventing the system from being overwhelmed by excessive requests. By counting and limiting user requests, the API can maintain performance and stability under high concurrency.
The main purpose of rate limiting is:
- Prevent excessive requests from overloading the server.
- Restrict malicious or abnormal behavior.
- Improve API availability and ensure fair allocation of resources.
Common rate limiting algorithms
1. Leaky Bucket Algorithm
The leaky bucket algorithm processes requests at a fixed rate within a certain time window. If the request rate exceeds a predetermined limit, it will be discarded or delayed.
2. Token Bucket Algorithm
The token bucket algorithm is a flexible rate control mechanism suitable for handling burst traffic. Each request needs to obtain a token, and if the token bucket is empty, the request is discarded.
3. Fixed Window Counter
In a fixed time window, the counter records the number of requests, and once the request exceeds the limit, subsequent requests will be denied.
4. Sliding Window Counter
Sliding windows are more refined than fixed windows. Each request is counted within a sliding time window, which can smooth flow control.
Through these algorithms, the API can control the number of requests initiated by different users or clients within a specified time, ensuring the smooth operation of the system.
2. Redis implements distributed rate limiting
Redis is a high-performance key-value database that is widely used in scenarios such as caching, message queueing and distributed rate limiting. In distributed systems, Redis provides efficient data storage and sharing mechanisms, which can help different server instances share request counting information, thereby achieving rate limiting across servers.
Redis implementation ideas
We use Redis's SETEX command to set a key-value pair, where the key is the user ID (such as IP or user ID) and the value is the request count. Each time the user initiates a request, we first check whether the key exists. If present, check if its value exceeds the limit; if not, set a new key and start counting. Rate limiting can be achieved by setting the expiration time of the key.
Sample code
from fastapi import FastAPI, Request, HTTPException import redis import time app = FastAPI() # Connect to Redis Serverr = (host='localhost', port=6379, db=0) # Limit parametersLIMIT = 100 # 100 requests per minuteTIME_WINDOW = 60 # 1 minute @("http") async def rate_limit(request: Request, call_next): ip_address = current_time = int(()) # Construct Redis keys redis_key = f"rate_limit:{ip_address}:{current_time // TIME_WINDOW}" # Use Redis's INCR command to increase the count request_count = (redis_key) if request_count == 1: # Set the expiration time to 60 seconds (time window size) (redis_key, TIME_WINDOW) if request_count > LIMIT: raise HTTPException(status_code=429, detail="Too many requests") response = await call_next(request) return response
Code parsing
- (redis_key): Redis's INCR command can atomically increment the value of a key. If the key does not exist, it will first create the key and set the initial value to 1.
- (redis_key, TIME_WINDOW): Sets the expiration time of the key so that the count automatically resets within each time window.
- 429 Too Many Requests: When the number of requests exceeds the limit, the return of the 429 status code indicates that the request frequency limit is exceeded.
This method can effectively prevent a single IP address from sending too many requests in a short time, ensuring the availability and performance of the API.
3. Common strategies to prevent DDoS attacks
DDoS (Distributed Denial of Service) attacks flood the target server with a large number of malicious requests, resulting in the system being unavailable. To prevent this kind of attack, in addition to traditional firewall and load balancing strategies, we also need to implement protection at the API level.
Common defense strategies
Blacklist/whitelist
IP-based access control can effectively block traffic from known attack sources. By blacklisting malicious IPs, requests from these IPs can be prevented from entering the system.
2. Request rate limit
Use rate limiting algorithms (such as leaky buckets or token buckets) to control the frequency of requests to avoid excessive requests from a single source.
3. Behavior analysis and intelligent protection
Identify and block abnormal traffic by analyzing the behavior patterns of requests. For example, the request header, request frequency, request path, etc. that detects exceptions.
4. Verification code and identity verification
In key links of user requests, such as login, registration, payment, etc., add verification codes or secondary authentication to prevent malicious robots from being automated attacks.
Sample code: IP-based rate limiting and verification code
from fastapi import FastAPI, HTTPException, Request from import JSONResponse from pydantic import BaseModel import redis import time import random app = FastAPI() r = (host='localhost', port=6379, db=0) LIMIT = 100 TIME_WINDOW = 60 CAPTCHA_THRESHOLD = 10 @("/login") async def login(request: Request, user: BaseModel): ip_address = current_time = int(()) redis_key = f"rate_limit:{ip_address}:{current_time // TIME_WINDOW}" request_count = (redis_key) if request_count == 1: (redis_key, TIME_WINDOW) if request_count > LIMIT: # Start the verification code mechanism captcha = (1000, 9999) return JSONResponse(content={"captcha_required": True, "captcha": captcha}, status_code=400) return {"message": "Login successful"}
Code parsing
When the request frequency exceeds the limit, a verification code is returned, and the user needs to verify the verification code to continue the operation.
This method effectively prevents automated attacks and reduces the success rate of malicious requests.
4. Access frequency control based on IP or user identity
In addition to global rate limiting, access frequency can be limited individually based on IP address or user identity. Through this method, the access permissions of the API can be controlled more refinedly, and a specific user or IP can be used up too much resources.
Sample code: Access frequency control based on user identity
from fastapi import Depends, HTTPException, Request from pydantic import BaseModel @("/user_dashboard") async def user_dashboard(user_id: str, request: Request): user_limit_key = f"user:{user_id}:rate_limit" ip_limit_key = f"ip:{}:rate_limit" # User access frequency limit user_request_count = (user_limit_key) if user_request_count == 1: (user_limit_key, TIME_WINDOW) if user_request_count > LIMIT: raise HTTPException(status_code=429, detail="User request limit exceeded") # IP access frequency limit ip_request_count = (ip_limit_key) if ip_request_count == 1: (ip_limit_key, TIME_WINDOW) if ip_request_count > LIMIT: raise HTTPException(status_code=429, detail="IP request limit exceeded") return {"message": "Welcome to the user dashboard"}
Code parsing
user_id: Each user has an independent request count to prevent a certain user from abuseing the API.
: The request count of IP addresses to prevent the same IP address from abuse of API.
Set limits according to the access frequency of the user and IP respectively, which improves the control accuracy.
This is the article about using Redis to implement request limits and rate limits. For more related Redis request limits and rate limits, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!