用更簡單的話來說,速率限制,它是一種限制使用者或客戶端在給定時間範圍內可以向 API 發出請求數量的技術。過去,當您嘗試存取天氣或笑話 API 時,您可能遇到過收到「超出速率限制」訊息的情況。關於為什麼要限制 API 的速率有很多爭論,但一些重要的爭論是合理使用它、確保其安全性、保護資源免於過載等。
在本部落格中,我們將使用 Gin 框架使用 Golang 建立一個 HTTP 伺服器,使用 Redis 對端點應用速率限制功能,並儲存某個時間範圍內 IP 向伺服器發出的請求總數。如果超過我們設定的限制,我們會給出錯誤訊息。
如果你不知道 Gin 和 Redis 是什麼。 Gin 是一個用 Golang 寫的 Web 框架。它有助於創建一個簡單而快速的伺服器,而無需編寫大量程式碼。 Redis 它是一個記憶體中的鍵值資料存儲,可以用作資料庫或快取功能。
先決條件
- 熟悉 Golang、Gin 和 Redis
- 一個 Redis 實例(我們可以使用 Docker 或遠端機器)
現在,讓我們開始吧。
要初始化項目,請執行 go mod init
然後讓我們使用 Gin 框架建立一個簡單的 HTTP 伺服器,然後套用對其進行速率限制的邏輯。您可以複製下面的程式碼。這是非常基本的。當我們點擊 /message 端點時,伺服器將回覆一則訊息。
複製以下程式碼後,執行 go mod tidy 即可自動安裝我們匯入的軟體包。
package main import ( "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/message", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "You can make more requests", }) }) r.Run(":8081") //listen and serve on localhost:8081 }
我們可以透過在終端機中執行 go run main.go 來運行伺服器,並在終端機中看到此訊息。
要測試它,我們可以存取 localhost:8081/message 我們將在瀏覽器中看到此訊息。
現在我們的伺服器正在運行,讓我們為 /message 路由設定速率限制功能。我們將使用 go-redis/redis_rate 套件。感謝這個套件的創建者,我們不需要從頭開始編寫處理和檢查限制的邏輯。它將為我們完成所有繁重的工作。
以下是實現限速功能後的完整程式碼。我們會理解其中的每一點。只是儘早給出完整的程式碼,以避免任何混淆並了解不同部分如何協同工作。
複製程式碼後,執行 go mod tidy 來安裝所有匯入的軟體包。現在讓我們跳轉並理解程式碼(在程式碼片段下方)。
package main import ( "github.com/gin-gonic/gin" ) func main() { r := gin.Default() r.GET("/message", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "You can make more requests", }) }) r.Run(":8081") //listen and serve on localhost:8081 }
我們先直接跳到rateLimiter()函數來理解一下。該函數需要一個參數,即請求的 IP 位址,我們可以透過主函數中的 c.ClientIP() 來取得該位址。如果達到限制,我們將傳回錯誤,否則將其保持為零。大部分程式碼是我們從官方 GitHub 儲存庫中取得的樣板程式碼。這裡需要仔細研究的關鍵功能是 limiter.Allow() 函數。 Addr:取得 Redis 實例的 URL 路徑值。我正在使用 Docker 在本地運行它。您可以使用任何內容,只需確保相應地替換 URL 即可。
package main import ( "context" "errors" "net/http" "github.com/gin-gonic/gin" "github.com/go-redis/redis_rate/v10" "github.com/redis/go-redis/v9" ) func main() { r := gin.Default() r.GET("/message", func(c *gin.Context) { err := rateLimiter(c.ClientIP()) if err != nil { c.JSON(http.StatusTooManyRequests, gin.H{ "message": "you have hit the limit", }) return } c.JSON(http.StatusOK, gin.H{ "message": "You can make more requests", }) }) r.Run(":8081") } func rateLimiter(clientIP string) error { ctx := context.Background() rdb := redis.NewClient(&redis.Options{ Addr: "localhost:6379", }) limiter := redis_rate.NewLimiter(rdb) res, err := limiter.Allow(ctx, clientIP, redis_rate.PerMinute(10)) if err != nil { panic(err) } if res.Remaining == 0 { return errors.New("Rate") } return nil }
它有三個參數,第一個是 ctx,第二個是 Key,Redis 資料庫的 Key(值的鍵),第三個是限制。因此,函數將 clientIP 位址儲存為鍵,將預設限制儲存為值,並在發出請求時減少它。這種結構的原因是Redis資料庫需要唯一標識和唯一鍵來儲存鍵值對類型的數據,並且每個IP位址都以自己的方式唯一,這就是為什麼我們使用IP位址而不是用戶名,第三個參數redis_rate.PerMinute(10) 可以依照我們的需求進行修改,我們可以設定限制PerSecond, PerHour,等等,並設定括號內的值,表示每分鐘/秒/小時可以發出多少個請求。在我們的例子中,它是每分鐘 10 個。是的,設定就這麼簡單。
最後,我們透過 res.Remaining 檢查是否有剩餘配額。如果它為零,我們將返回錯誤訊息,否則我們將返回 nil。例如,您也可以執行 res.Limit.Rate 來檢查限制率等。您可以嘗試並深入研究它。
現在是 main() 函數:
res, err := limiter.Allow(ctx, clientIP, redis_rate.PerMinute(10))
一切都幾乎一樣。在 /message 路由中,現在每次路由命中時,我們都會呼叫rateLimit()函數並向其傳遞一個 ClientIP 位址,並將傳回值(錯誤)值儲存在 err 變數中。如果發生錯誤,我們將回傳 429,即 http.StatusTooManyRequests,以及一則訊息「message」:「您已達到限制」。如果該人有剩餘限制並且rateLimit()沒有返回錯誤,它將正常工作,就像之前所做的那樣並服務於請求。
這就是所有的解釋。現在讓我們測試一下工作情況。透過執行相同的命令重新運行伺服器。我們將第一次看到之前收到的相同訊息。現在刷新您的瀏覽器 10 次(因為我們設定了每分鐘 10 次的限制),您將在瀏覽器中看到錯誤訊息。
我們也可以透過查看終端機中的日誌來驗證這一點。 Gin 提供了很好的開箱即用的登入功能。一分鐘後它將恢復我們的限製配額。
本部落格到此結束,我希望您喜歡閱讀,就像我喜歡寫這篇文章一樣。我很高興您能堅持到最後,非常感謝您的支持。我還經常在 X (Twitter) 上談論 Golang 以及其他內容,例如開源和 Docker。你可以在那裡聯絡我。
以上是使用 Redis 對 Golang API 進行速率限制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Golang適合快速開發和並發編程,而C 更適合需要極致性能和底層控制的項目。 1)Golang的並發模型通過goroutine和channel簡化並發編程。 2)C 的模板編程提供泛型代碼和性能優化。 3)Golang的垃圾回收方便但可能影響性能,C 的內存管理複雜但控制精細。

goimpactsdevelopmentpositationality throughspeed,效率和模擬性。 1)速度:gocompilesquicklyandrunseff,IdealforlargeProjects.2)效率:效率:ITScomprehenSevestAndardArdardArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdArdEcceSteral Depentencies,增強的Depleflovelmentimency.3)簡單性。

C 更適合需要直接控制硬件資源和高性能優化的場景,而Golang更適合需要快速開發和高並發處理的場景。 1.C 的優勢在於其接近硬件的特性和高度的優化能力,適合遊戲開發等高性能需求。 2.Golang的優勢在於其簡潔的語法和天然的並發支持,適合高並發服務開發。

Golang在实际应用中表现出色,以简洁、高效和并发性著称。1)通过Goroutines和Channels实现并发编程,2)利用接口和多态编写灵活代码,3)使用net/http包简化网络编程,4)构建高效并发爬虫,5)通过工具和最佳实践进行调试和优化。

Go語言的核心特性包括垃圾回收、靜態鏈接和並發支持。 1.Go語言的並發模型通過goroutine和channel實現高效並發編程。 2.接口和多態性通過實現接口方法,使得不同類型可以統一處理。 3.基本用法展示了函數定義和調用的高效性。 4.高級用法中,切片提供了動態調整大小的強大功能。 5.常見錯誤如競態條件可以通過gotest-race檢測並解決。 6.性能優化通過sync.Pool重用對象,減少垃圾回收壓力。

Go語言在構建高效且可擴展的系統中表現出色,其優勢包括:1.高性能:編譯成機器碼,運行速度快;2.並發編程:通過goroutines和channels簡化多任務處理;3.簡潔性:語法簡潔,降低學習和維護成本;4.跨平台:支持跨平台編譯,方便部署。

關於SQL查詢結果排序的疑惑學習SQL的過程中,常常會遇到一些令人困惑的問題。最近,筆者在閱讀《MICK-SQL基礎�...


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

記事本++7.3.1
好用且免費的程式碼編輯器

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

WebStorm Mac版
好用的JavaScript開發工具