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

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

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

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]刪除
最新教學 更多>
  • 了解 Javascript 代理和 Reflect API
    了解 Javascript 代理和 Reflect API
    介绍 在 Javascript 中,代理使您能够捕获特定对象操作并自定义它们。代理充当对象和“现实世界”之间的中介。因此,您可以增强对象的基本操作以实现更复杂的逻辑或重新定义基本操作以满足您的需求。 用例包括: 记录属性访问,对于调试很有用 验证与对象的任何交互(例如表单验证) 帮...
    程式設計 發佈於2024-11-08
  • 使用 Flexbox 探索嵌套
    使用 Flexbox 探索嵌套
    Flexbox 是一個多功能工具,可在網路上建立響應式且靈活的佈局。 Flexbox 中更高級的技術之一是嵌套,您可以在 Flexbox 中使用 Flexbox 來管理複雜的佈局。這篇文章是我回顧從 Wes Bos 的免費 Flexbox 課程中學到的知識的方式,我很高興與您分享這些見解。 我最近...
    程式設計 發佈於2024-11-08
  • 在 PHP 中使用 Cloudflare 時如何檢索實際訪客 IP 位址?
    在 PHP 中使用 Cloudflare 時如何檢索實際訪客 IP 位址?
    在PHP 中使用Cloudflare 檢索訪客IP 位址追蹤網站訪客時,記錄他們的IP 位址是常見做法。但是,利用 Cloudflare 進行快取可能會帶來問題,因為傳回的 IP 位址可能是 Cloudflare 伺服器的 IP 位址。本文探討了利用 Cloudflare 時檢索實際訪客 IP 位址...
    程式設計 發佈於2024-11-08
  • 如何使用內省、點擊和豐富格式為 Python CLI 建立互動式聊天
    如何使用內省、點擊和豐富格式為 Python CLI 建立互動式聊天
    如果您曾经想让您的 CLI 更具交互性和动态性,构建实时命令交互系统可能是答案。通过利用 Python 的自省功能、用于管理命令的 Click 以及用于格式化输出的 Rich,您可以创建一个强大、灵活的 CLI,以智能地响应用户输入。您的 CLI 可以自动发现并执行命令,而不是手动对每个命令进行硬编...
    程式設計 發佈於2024-11-08
  • 從初學者到黑客的專案想法
    從初學者到黑客的專案想法
    今天我準備了10個從初級到大神級別的專案創意。如果你完成了所有這些,你就是一個神程式設計師。讓我們從小事做起。 初學者 1.待辦事項 每個項目清單中唯一的一項是待辦事項應用程式。那麼,我又遇到同樣的事情了呢?因此,建立一個基本輸入和按鈕以及一個清單。用於輸入待辦事項名稱的輸入以及將...
    程式設計 發佈於2024-11-08
  • 如何透過內容腳本建立後台腳本與注入腳本的通訊?
    如何透過內容腳本建立後台腳本與注入腳本的通訊?
    將訊息從後台腳本發送到內容腳本,然後發送到注入腳本問題:儘管嘗試將訊息從後台頁面發送到內容腳本,然後發送到注入腳本,但該過程未能按預期工作。內容腳本無法接收來自後台腳本的訊息。 解決方案:此問題是由內容腳本注入的方式引起的。載入擴充功能時,它不會自動將內容腳本注入現有標籤中。僅當建立新選項卡或載入擴...
    程式設計 發佈於2024-11-08
  • 如何解決 PHP 中 file_get_contents() 的 SSL 逾時和加密啟用錯誤?
    如何解決 PHP 中 file_get_contents() 的 SSL 逾時和加密啟用錯誤?
    解決了file_get_contents() 的SSL 逾時和加密啟用錯誤在PHP 中,當使用file_get_contents() 從HTTPS 頁面檢索內容時,可能會遇到與SSL 加密啟用相關的錯誤。此類錯誤之一是:Warning: file_get_contents(): SSL: crypt...
    程式設計 發佈於2024-11-08
  • 如何監控 Guzzle Http 用戶端 – PHP 快速提示
    如何監控 Guzzle Http 用戶端 – PHP 快速提示
    Guzzle 是一款流行的 PHP HTTP 客户端,可以轻松发送 HTTP 请求和创建 Web 服务库。最流行的 PHP 框架提供了内部 Http Client 服务,它们只是 Guzzle Http Client 的定制实现: Laravel Http 客户端 Symfony Http 客户端 ...
    程式設計 發佈於2024-11-08
  • 為什麼 Python 在方法中需要明確的「Self」參數?
    為什麼 Python 在方法中需要明確的「Self」參數?
    揭秘Python方法中的「Self」參數與某些程式語言不同,物件引用是用「this」關鍵字式定義的, Python 要求在方法定義中明確包含「self」參數。這種設計決策提出了一個問題:它是故意的還是實現限制的問題。 在 Python 中,「self」參數明確地建立了方法與其類別實例之間的關係。它提...
    程式設計 發佈於2024-11-08
  • 使用 Gin/Golang 時如何處理空請求主體:綁定與除錯技術指南
    使用 Gin/Golang 時如何處理空請求主體:綁定與除錯技術指南
    Gin/Golang 中請求正文為空使用Gin 處理POST 請求時,偶爾可能會遇到請求正文顯示為空的問題是空的。這可能會令人沮喪,尤其是當您希望從客戶端接收資料時。此問題的一個常見原因是嘗試直接列印正文。 Gin 將請求內文表示為介面類型 ReadCloser。但列印該介面的字串值並不會洩漏實際的...
    程式設計 發佈於2024-11-08
  • Python 列表理解
    Python 列表理解
    Python 最酷的事情之一是清單推導式如何讓在一行程式碼中建立和操作清單變得非常容易。列表理解是一種透過轉換和過濾現有清單中的元素來建立新清單的簡潔方法。這個特性是 Python 使程式碼更具可讀性和高效性的眾多方法之一,對於初學者來說是一個很好的學習工具。在這裡閱讀更多範例...... 奧利佛 ...
    程式設計 發佈於2024-11-08
  • 如何在 Gin 中組織路由:分組路由定義指南?
    如何在 Gin 中組織路由:分組路由定義指南?
    如何在 Gin 中組織路由為了避免路由定義使主文件混亂,您可以將路由分組到單獨的文件中。這種方法可以實現更好的程式碼組織和可維護性。 要建立嵌套路由分組,您可以將路由器變數儲存在結構體或全域變數中。然後,各個檔案可以將處理程序新增至此共用路由器實例。 範例實作routes.gopackage app...
    程式設計 發佈於2024-11-08
  • Leetcode鍊錶問題
    Leetcode鍊錶問題
    反向鍊錶(LeetCode #206) 難度:簡單 概念:迭代與遞歸方法。 合併兩個排序清單 (LeetCode #21) 難度:簡單 概念:鍊錶遍歷與合併技術。 從清單結束時刪除第 N 個節點 **(LeetCode #19) **難度:中等 概念:兩指針技術(慢指針和快指針)。 鍊錶循環...
    程式設計 發佈於2024-11-08
  • 如何在 C++ 容器中儲存異質物件:boost::any 或自訂實作?
    如何在 C++ 容器中儲存異質物件:boost::any 或自訂實作?
    在C 容器中儲存異質物件C 容器通常需要同質元素,這意味著它們只能保存單一類型的對象。但是,在某些情況下,您可能需要一個可以容納混合資料類型的容器。本文探討如何使用 boost::any 函式庫和自訂方法來實現此目的。 使用 boost::anyboost::any 是一個模板類別可以容納任何 C ...
    程式設計 發佈於2024-11-08
  • 使用 Pandas 掌握數據分析:從數據中釋放洞察力
    使用 Pandas 掌握數據分析:從數據中釋放洞察力
    資料分析是資料科學的核心,Python 的 Pandas 函式庫是一個強大的工具,可以讓這項任務變得更輕鬆、更有效率。無論您使用簡單的電子表格還是大型資料集,Pandas 都可以讓您像專業人士一樣靈活地操作、分析和視覺化資料。在本文中,我們將深入探討 Pandas 的基礎知識,涵蓋從資料操作到進階分...
    程式設計 發佈於2024-11-08

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

Copyright© 2022 湘ICP备2022001581号-3