速率限制是 Web 開發和 API 設計中的關鍵概念。它確保使用者或系統在特定時間範圍內只能向伺服器發出有限數量的請求。在這篇文章中,我們將探討什麼是速率限制、為什麼它很重要,以及如何在 Go 中實作一個簡單的速率限制器。
什麼是速率限制?
想像一個主題樂園,裡面有雲霄飛車,每 10 分鐘只能容納 10 人。如果超過 10 人試圖在該時間內上車,他們將不得不等待。這個類比反映了軟體系統中速率限制的原理。
用技術術語來說,速率限制限制客戶端(例如使用者、裝置或 IP 位址)在預定義時間內可以傳送到伺服器的請求數量。它有幫助:
- 防止濫用並確保公平使用資源。
- 保護伺服器不被過多的流量淹沒。
- 避免過度使用第三方 API 或服務,造成高昂代價。
例如,API 可能允許每位使用者每分鐘 100 個請求。如果使用者超出此限制,伺服器將拒絕進一步的請求,直到限制重置。
速率限制如何運作?
實現速率限制的常見方法是透過令牌桶演算法。其工作原理如下:
- 儲存桶以固定數量的令牌(例如 10)開始。
- 每個請求都會從儲存桶中刪除一個令牌。
- 如果桶中沒有剩餘令牌,則請求被拒絕。
- 代幣會以穩定的速度(例如每秒 1 個代幣)補充,直到桶裝滿。
在 Go 中建立一個簡單的速率限制器
讓我們深入研究在 Go 中建立一個速率限制器,將每個客戶端限制為每分鐘 3 個請求。
第 1 步:定義速率限制器結構
我們將使用sync.Mutex來確保執行緒安全性並儲存令牌數量、最大容量和填充率等資訊。
package main import ( "sync" "time" ) type RateLimiter struct { tokens float64 // Current number of tokens maxTokens float64 // Maximum tokens allowed refillRate float64 // Tokens added per second lastRefillTime time.Time // Last time tokens were refilled mutex sync.Mutex } func NewRateLimiter(maxTokens, refillRate float64) *RateLimiter { return &RateLimiter{ tokens: maxTokens, maxTokens: maxTokens, refillRate: refillRate, lastRefillTime: time.Now(), } }
第 2 步:實作令牌補充邏輯
代幣應根據上次充值以來的經過時間定期補充。
func (r *RateLimiter) refillTokens() { now := time.Now() duration := now.Sub(r.lastRefillTime).Seconds() tokensToAdd := duration * r.refillRate r.tokens += tokensToAdd if r.tokens > r.maxTokens { r.tokens = r.maxTokens } r.lastRefillTime = now }
第 3 步:檢查請求是否被允許
Allow 方法將根據可用令牌確定請求是否可以繼續。
func (r *RateLimiter) Allow() bool { r.mutex.Lock() defer r.mutex.Unlock() r.refillTokens() if r.tokens >= 1 { r.tokens-- return true } return false }
第 4 步:對每個 IP 應用速率限制
為了限制每個客戶端的請求,我們將建立 IP 位址到各自速率限制器的對應。
type IPRateLimiter struct { limiters map[string]*RateLimiter mutex sync.Mutex } func NewIPRateLimiter() *IPRateLimiter { return &IPRateLimiter{ limiters: make(map[string]*RateLimiter), } } func (i *IPRateLimiter) GetLimiter(ip string) *RateLimiter { i.mutex.Lock() defer i.mutex.Unlock() limiter, exists := i.limiters[ip] if !exists { // Allow 3 requests per minute limiter = NewRateLimiter(3, 0.05) i.limiters[ip] = limiter } return limiter }
第 5 步:建立用於速率限制的中間件
最後,我們將建立一個 HTTP 中間件,對每個客戶端實作速率限制。
package main import ( "sync" "time" ) type RateLimiter struct { tokens float64 // Current number of tokens maxTokens float64 // Maximum tokens allowed refillRate float64 // Tokens added per second lastRefillTime time.Time // Last time tokens were refilled mutex sync.Mutex } func NewRateLimiter(maxTokens, refillRate float64) *RateLimiter { return &RateLimiter{ tokens: maxTokens, maxTokens: maxTokens, refillRate: refillRate, lastRefillTime: time.Now(), } }
第 6 步:設定伺服器
以下是如何將它們連接在一起並測試速率限制器。
func (r *RateLimiter) refillTokens() { now := time.Now() duration := now.Sub(r.lastRefillTime).Seconds() tokensToAdd := duration * r.refillRate r.tokens += tokensToAdd if r.tokens > r.maxTokens { r.tokens = r.maxTokens } r.lastRefillTime = now }
測試速率限制器
啟動伺服器並使用curl或瀏覽器測試:
func (r *RateLimiter) Allow() bool { r.mutex.Lock() defer r.mutex.Unlock() r.refillTokens() if r.tokens >= 1 { r.tokens-- return true } return false }
- 快速發送 3 個請求:全部都應該成功。
- 在同一分鐘內發送第四個請求:您應該會看到「超出速率限制」訊息。
- 等待 20 秒,然後重試:儲存桶重新裝滿,請求應該會成功。
原始碼
GitHub 儲存庫
以上是初學者的速率限制:它是什麼以及如何在 Go 中構建速率限制的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Golangisidealforbuildingscalablesystemsduetoitsefficiencyandconcurrency,whilePythonexcelsinquickscriptinganddataanalysisduetoitssimplicityandvastecosystem.Golang'sdesignencouragesclean,readablecodeanditsgoroutinesenableefficientconcurrentoperations,t

Golang在並發性上優於C ,而C 在原始速度上優於Golang。 1)Golang通過goroutine和channel實現高效並發,適合處理大量並發任務。 2)C 通過編譯器優化和標準庫,提供接近硬件的高性能,適合需要極致優化的應用。

選擇Golang的原因包括:1)高並發性能,2)靜態類型系統,3)垃圾回收機制,4)豐富的標準庫和生態系統,這些特性使其成為開發高效、可靠軟件的理想選擇。

Golang適合快速開發和並發場景,C 適用於需要極致性能和低級控制的場景。 1)Golang通過垃圾回收和並發機制提升性能,適合高並發Web服務開發。 2)C 通過手動內存管理和編譯器優化達到極致性能,適用於嵌入式系統開發。

Golang在編譯時間和並發處理上表現更好,而C 在運行速度和內存管理上更具優勢。 1.Golang編譯速度快,適合快速開發。 2.C 運行速度快,適合性能關鍵應用。 3.Golang並發處理簡單高效,適用於並發編程。 4.C 手動內存管理提供更高性能,但增加開發複雜度。

Golang在Web服務和系統編程中的應用主要體現在其簡潔、高效和並發性上。 1)在Web服務中,Golang通過強大的HTTP庫和並發處理能力,支持創建高性能的Web應用和API。 2)在系統編程中,Golang利用接近硬件的特性和對C語言的兼容性,適用於操作系統開發和嵌入式系統。

Golang和C 在性能對比中各有優劣:1.Golang適合高並發和快速開發,但垃圾回收可能影響性能;2.C 提供更高性能和硬件控制,但開發複雜度高。選擇時需綜合考慮項目需求和團隊技能。

Golang适合高性能和并发编程场景,Python适合快速开发和数据处理。1.Golang强调简洁和高效,适用于后端服务和微服务。2.Python以简洁语法和丰富库著称,适用于数据科学和机器学习。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

禪工作室 13.0.1
強大的PHP整合開發環境

SublimeText3漢化版
中文版,非常好用

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)