首頁 >後端開發 >Golang >在您的 Go API 中新增 API 速率限制

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

Linda Hamilton
Linda Hamilton原創
2024-10-07 10:49:30418瀏覽

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 太多請求 回應。


接下來是什麼?

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

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

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

以上是在您的 Go API 中新增 API 速率限制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn