欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Redis實現(xiàn)請求限制與速率限制

 更新時間:2025年04月10日 10:24:11   作者:Switch616  
API速率限制(Rate Limiting)是控制用戶訪問API的請求速率的一種機制,防止系統(tǒng)被過多請求淹沒,下面我們來看看如何使用Redis和FastAPI實現(xiàn)請求限制與速率控制吧

1. API速率限制的基本概念

API速率限制(Rate Limiting)是控制用戶訪問API的請求速率的一種機制,防止系統(tǒng)被過多請求淹沒。通過對用戶的請求進行計數(shù)與限制,API能夠在高并發(fā)情況下維持性能與穩(wěn)定性。

速率限制的主要目的是:

  • 防止過多請求導(dǎo)致服務(wù)器負載過高。
  • 限制惡意或非正常行為。
  • 提高API的可用性,確保公平分配資源。

常見的速率限制算法

1.漏桶算法(Leaky Bucket Algorithm)

漏桶算法在一定時間窗口內(nèi)以固定速率處理請求,若請求速率超過預(yù)定限度,則會被丟棄或延遲。

2.令牌桶算法(Token Bucket Algorithm)

令牌桶算法是一種靈活的速率控制機制,適合處理突發(fā)流量。每個請求都需要獲取一個令牌,如果令牌桶為空,則請求被丟棄。

3.固定窗口計數(shù)法(Fixed Window Counter)

在固定時間窗口內(nèi),計數(shù)器記錄請求的次數(shù),一旦請求超出限制,后續(xù)請求將被拒絕。

4.滑動窗口計數(shù)法(Sliding Window Counter)

滑動窗口比固定窗口更加精細,每個請求都在一個滑動的時間窗口內(nèi)進行計數(shù),能平滑流量控制。

通過這些算法,API能夠控制不同用戶或客戶端在指定時間內(nèi)發(fā)起的請求數(shù)量,確保系統(tǒng)的平穩(wěn)運行。

2. Redis實現(xiàn)分布式速率限制

Redis是一個高性能的鍵值數(shù)據(jù)庫,廣泛用于緩存、消息隊列和分布式速率限制等場景。在分布式系統(tǒng)中,Redis提供了高效的數(shù)據(jù)存儲和共享機制,可以幫助不同服務(wù)器實例共享請求計數(shù)信息,從而實現(xiàn)跨服務(wù)器的速率限制。

Redis的實現(xiàn)思路

我們使用Redis的SETEX命令設(shè)置一個鍵值對,其中鍵為用戶標識(例如IP或用戶ID),值為請求計數(shù)。每次用戶發(fā)起請求時,我們先檢查該鍵是否存在。如果存在,檢查其值是否超過限額;如果不存在,設(shè)置新的鍵并開始計數(shù)。通過設(shè)置鍵的過期時間,可以實現(xiàn)速率限制。

示例代碼

from fastapi import FastAPI, Request, HTTPException
import redis
import time

app = FastAPI()

# 連接Redis服務(wù)器
r = redis.Redis(host='localhost', port=6379, db=0)

# 限制參數(shù)
LIMIT = 100  # 每分鐘100次請求
TIME_WINDOW = 60  # 1分鐘

@app.middleware("http")
async def rate_limit(request: Request, call_next):
    ip_address = request.client.host
    current_time = int(time.time())
    
    # 構(gòu)造Redis的鍵
    redis_key = f"rate_limit:{ip_address}:{current_time // TIME_WINDOW}"
    
    # 使用Redis的INCR命令增加計數(shù)
    request_count = r.incr(redis_key)
    
    if request_count == 1:
        # 設(shè)置過期時間為60秒(時間窗口大?。?
        r.expire(redis_key, TIME_WINDOW)
    
    if request_count > LIMIT:
        raise HTTPException(status_code=429, detail="Too many requests")
    
    response = await call_next(request)
    return response

代碼解析

  • r.incr(redis_key):Redis的INCR命令可以原子性地遞增鍵的值。如果鍵不存在,它會先創(chuàng)建鍵并設(shè)置初值為1。
  • r.expire(redis_key, TIME_WINDOW):設(shè)置鍵的過期時間,使得計數(shù)在每個時間窗口內(nèi)自動重置。
  • 429 Too Many Requests:當(dāng)請求次數(shù)超過限制時,返回429狀態(tài)碼表示超出請求頻率限制。

這種方式可以有效防止單個IP地址在短時間內(nèi)發(fā)送過多請求,保障API的可用性與性能。

3. 防止DDoS攻擊的常見策略

DDoS(Distributed Denial of Service)攻擊通過大量惡意請求淹沒目標服務(wù)器,導(dǎo)致系統(tǒng)不可用。為了防止這種攻擊,除了傳統(tǒng)的防火墻和負載均衡策略外,我們還需要在API層面實現(xiàn)防護。

常見的防御策略

1.IP黑名單/白名單

基于IP的訪問控制可以有效阻止已知攻擊源的流量。通過將惡意IP加入黑名單,可以防止這些IP的請求進入系統(tǒng)。

2.請求速率限制

利用速率限制算法(如漏桶或令牌桶),控制請求頻率,避免單個來源發(fā)送過多請求。

3.行為分析與智能防護

通過分析請求的行為模式,識別并阻止異常流量。例如,檢測異常的請求頭、請求頻率、請求路徑等。

4.驗證碼與身份驗證

在用戶請求的關(guān)鍵環(huán)節(jié),如登錄、注冊、支付等,加入驗證碼或二次身份驗證,防止惡意機器人自動化攻擊。

示例代碼:基于IP的速率限制和驗證碼

from fastapi import FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import redis
import time
import random

app = FastAPI()

r = redis.Redis(host='localhost', port=6379, db=0)
LIMIT = 100
TIME_WINDOW = 60
CAPTCHA_THRESHOLD = 10

@app.post("/login")
async def login(request: Request, user: BaseModel):
    ip_address = request.client.host
    current_time = int(time.time())
    
    redis_key = f"rate_limit:{ip_address}:{current_time // TIME_WINDOW}"
    request_count = r.incr(redis_key)
    
    if request_count == 1:
        r.expire(redis_key, TIME_WINDOW)
    
    if request_count > LIMIT:
        # 啟動驗證碼機制
        captcha = random.randint(1000, 9999)
        return JSONResponse(content={"captcha_required": True, "captcha": captcha}, status_code=400)
    
    return {"message": "Login successful"}

代碼解析

當(dāng)請求頻率超過限制時,返回一個驗證碼,用戶需要通過驗證碼驗證來繼續(xù)操作。

這種方式有效阻止了自動化攻擊,減少了惡意請求的成功率。

4. 基于IP或用戶身份的訪問頻率控制

除了全局的速率限制外,還可以根據(jù)IP地址或用戶身份來單獨限制訪問頻率。通過這種方法,可以更精細化地控制API的訪問權(quán)限,避免某個特定用戶或IP占用過多資源。

示例代碼:基于用戶身份的訪問頻率控制

from fastapi import Depends, HTTPException, Request
from pydantic import BaseModel

@app.get("/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:{request.client.host}:rate_limit"
    
    # 用戶訪問頻率限制
    user_request_count = r.incr(user_limit_key)
    if user_request_count == 1:
        r.expire(user_limit_key, TIME_WINDOW)
    
    if user_request_count > LIMIT:
        raise HTTPException(status_code=429, detail="User request limit exceeded")
    
    # IP訪問頻率限制
    ip_request_count = r.incr(ip_limit_key)
    if ip_request_count == 1:
        r.expire(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"}

代碼解析

user_id:每個用戶有獨立的請求計數(shù),防止某個用戶濫用API。

request.client.host:IP地址的請求計數(shù),防止同一個IP地址濫用API。

根據(jù)用戶和IP的訪問頻率分別設(shè)置限制,提高了控制精度。

到此這篇關(guān)于使用Redis實現(xiàn)請求限制與速率限制的文章就介紹到這了,更多相關(guān)Redis請求限制與速率限制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Redis Lua腳本的使用教程

    Redis Lua腳本的使用教程

    在Redis的學(xué)習(xí)中,Lua腳本是一項強大的高級特性,它允許用戶在Redis中執(zhí)行復(fù)雜的操作,本文就來介紹一下Redis Lua,腳本的使用教程,感興趣的可以了解一下
    2024-03-03
  • Redis字典實現(xiàn)、Hash鍵沖突及漸進式rehash詳解

    Redis字典實現(xiàn)、Hash鍵沖突及漸進式rehash詳解

    這篇文章主要介紹了Redis字典實現(xiàn)、Hash鍵沖突以及漸進式rehash的相關(guān)知識,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Redis優(yōu)惠券秒殺企業(yè)實戰(zhàn)

    Redis優(yōu)惠券秒殺企業(yè)實戰(zhàn)

    本文主要介紹了Redis優(yōu)惠券秒殺企業(yè)實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Redis數(shù)據(jù)結(jié)構(gòu)之鏈表與字典的使用

    Redis數(shù)據(jù)結(jié)構(gòu)之鏈表與字典的使用

    這篇文章主要介紹了Redis數(shù)據(jù)結(jié)構(gòu)之鏈表與字典的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • Redis實現(xiàn)分布式隊列淺析

    Redis實現(xiàn)分布式隊列淺析

    Redis將數(shù)據(jù)存儲在內(nèi)存中,使得讀寫速度非???,經(jīng)常被用來做緩存系統(tǒng),這里我們將redis用來做一個分布式的消息隊列。這篇文章主要介紹了使用redis來作為消息隊列,并且進行分布式主從配置,有需要的朋友可以參考借鑒,下面來一起看看吧。
    2016-11-11
  • Linux環(huán)境下升級redis的詳細步驟記錄

    Linux環(huán)境下升級redis的詳細步驟記錄

    這篇文章主要給大家介紹了關(guān)于Linux環(huán)境下升級redis的詳細步驟,描述了如何從舊版本升級到新版本Redis,包括備份舊數(shù)據(jù)、下載和安裝新版本、復(fù)制配置文件和數(shù)據(jù)、停止舊版本并啟動新版本的過程,需要的朋友可以參考下
    2024-12-12
  • Redis Sentinel實現(xiàn)哨兵模式搭建小結(jié)

    Redis Sentinel實現(xiàn)哨兵模式搭建小結(jié)

    這篇文章主要介紹了Redis Sentinel實現(xiàn)哨兵模式搭建小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • Redis學(xué)習(xí)教程之命令的執(zhí)行過程詳解

    Redis學(xué)習(xí)教程之命令的執(zhí)行過程詳解

    這篇文章主要給大家介紹了關(guān)于Redis學(xué)習(xí)教程之命令的執(zhí)行過程的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • redis緩存的簡單操作(get、put)

    redis緩存的簡單操作(get、put)

    這篇文章主要介紹了redis緩存的簡單操作,包括引入jedisjar包、配置redis、RedisDao需要的一些工具等,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Redis通過scan查找不過期的 key(方法詳解)

    Redis通過scan查找不過期的 key(方法詳解)

    SCAN 命令是一個基于游標的迭代器,每次被調(diào)用之后, 都會向用戶返回一個新的游標, 用戶在下次迭代時需要使用這個新游標作為 SCAN 命令的游標參數(shù), 以此來延續(xù)之前的迭代過程,對Redis scan 查找 key相關(guān)知識感興趣的朋友一起看看吧
    2021-08-08

最新評論