」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 在您的 Go API 中新增 API 速率限制

在您的 Go API 中新增 API 速率限制

發佈於2024-11-08
瀏覽:737

Adding API Rate Limiting to Your Go API

好吧,夥計們,到目前為止我們已經介紹了很多內容:JWT 身份驗證、資料庫連接、日誌記錄和錯誤處理。但是,當您的 API 開始受到請求的衝擊時會發生什麼?如果沒有控制,高流量可能會導致反應時間緩慢甚至停機。 ?

本週,我們將透過實施速率限制來控制流量來解決這個問題。我們將使用簡單有效的 golang.org/x/time/rate 套件。稍後,當我自己的 ThrottleX 解決方案準備就緒時,我將向您展示如何將其集成為更具可擴展性的選項。 (注意,請查看我的 GitHub(github.com/neelp03/throttlex)以獲取更新!請隨意評論您在其中看到的任何問題 o7)

為什麼要進行速率限制? ?

速率限制就像 API 的保鑣 — 它控制使用者在給定時間範圍內可以發出的請求數量。這可以防止您的 API 不堪重負,確保所有用戶順利、公平地存取。速率限制對於以下情況至關重要:

  • 防止濫用:阻止不良行為者或過度熱情的使用者淹沒您的 API。
  • 穩定性:即使在流量高峰期間,也能維持 API 的回應能力和可靠性。
  • 公平性:讓資源在使用者之間平等共享。

第 1 步:安裝時間/費率包

golang.org/x/time/rate 套件是擴展 Go 函式庫的一部分,提供了一個簡單的基於令牌的速率限制器。首先,您需要安裝它:


go get golang.org/x/time/rate


第 2 步:設定速率限制器

讓我們建立一個速率限制中間件來控制客戶端可以發出的請求數量。在此範例中,我們將客戶端限制為每分鐘 5 個請求


package main

import (
    "net/http"
    "golang.org/x/time/rate"
    "sync"
    "time"
)

// Create a struct to hold each client's rate limiter
type Client struct {
    limiter *rate.Limiter
}

// In-memory storage for clients
var clients = make(map[string]*Client)
var mu sync.Mutex

// Get a client's rate limiter or create one if it doesn't exist
func getClientLimiter(ip string) *rate.Limiter {
    mu.Lock()
    defer mu.Unlock()

    // If the client already exists, return the existing limiter
    if client, exists := clients[ip]; exists {
        return client.limiter
    }

    // Create a new limiter with 5 requests per minute
    limiter := rate.NewLimiter(5, 1)
    clients[ip] = &Client{limiter: limiter}
    return limiter
}


第 3 步:建立速率限制中介軟體

現在,讓我們在中間件中使用 getClientLimiter 函數,該函數將根據速率限制來限制存取。


func rateLimitingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ip := r.RemoteAddr
        limiter := getClientLimiter(ip)

        // Check if the request is allowed
        if !limiter.Allow() {
            http.Error(w, "Too Many Requests", http.StatusTooManyRequests)
            return
        }

        next.ServeHTTP(w, r)
    })
}


運作原理:

  1. 基於 IP 的限制:每個客戶端都透過其 IP 位址進行識別。我們檢查客戶端的 IP 並為其分配速率限制器。
  2. 請求檢查:limiter.Allow()方法檢查客戶端是否在速率限制內。如果是,則請求將繼續到下一個處理程序;如果沒有,我們會回覆 429 Too Many Requests.

第 4 步:在全球範圍內應用中間件 ?

現在讓我們將速率限制器連接到 API,以便每個請求都必須通過它:


func main() {
    db = connectDB()
    defer db.Close()

    r := mux.NewRouter()

    // Apply rate-limiting middleware globally
    r.Use(rateLimitingMiddleware)

    // Other middlewares
    r.Use(loggingMiddleware)
    r.Use(errorHandlingMiddleware)

    r.HandleFunc("/login", login).Methods("POST")
    r.Handle("/books", authenticate(http.HandlerFunc(getBooks))).Methods("GET")
    r.Handle("/books", authenticate(http.HandlerFunc(createBook))).Methods("POST")

    fmt.Println("Server started on port :8000")
    log.Fatal(http.ListenAndServe(":8000", r))
}


透過套用 r.Use(rateLimitingMiddleware),我們確保每個傳入請求在到達任何端點之前都會受到速率限制器的檢查。


第 5 步:測試速率限制?

啟動您的伺服器:


go run main.go


現在,讓我們使用一些請求來存取 API。可以使用帶有curl的循環來模擬連續多個請求:


for i in {1..10}; do curl http://localhost:8000/books; done


由於我們將限制設為每分鐘 5 個請求,一旦超出允許的速率,您應該會看到 429 Too Many Requests 回應。


接下來是什麼?

現在您已經有了它——使用 golang.org/x/time/rate 進行速率限制,以保持您的 API 在壓力下保持穩定和響應。速率限制對於任何可擴展 API 來說都是一個至關重要的工具,我們在這裡只是觸及了表面。

一旦 ThrottleX 準備就緒,我將發布後續教程,向您展示如何將其整合到 Go API 中,以獲得更大的靈活性和分散式速率限制。請關注我的 ThrottleX GitHub 存儲庫以獲取更新!

下週,我們將使用 Docker 容器化我們的 API,以便它可以在任何地方運行。請繼續關注,祝您編碼愉快! ??

版本聲明 本文轉載於:https://dev.to/neelp03/adding-api-rate-limiting-to-your-go-api-3fo8?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3