Web 系统经常面临短时间内大量客户端请求的挑战。 这可能会使服务器不堪重负,导致速度减慢或失败。 速率限制器通过控制每个客户端的请求频率来优雅地解决这个问题。 它充当看门人的角色,将 API 或服务调用限制在指定的时间窗口内。
速率限制提供了几个重要的好处:
滥用预防: 缓解过度或恶意请求,例如拒绝服务 (DoS) 攻击,防止系统过载。
资源管理:确保有效的资源分配,防止一个客户端独占服务器资源并影响其他客户端。
性能增强:通过防止请求泛滥,即使在高流量负载下也能保持应用程序响应能力。
改善用户体验:防止用户因请求过多而锁定或性能下降。
安全加强:通过限制请求率来帮助阻止暴力攻击或利用尝试。
让我们使用流行的 Chi 路由包和 golang.org/x/time/rate
包(采用令牌桶算法)来检查 Go 实现。 此示例使用 http.Handler
来控制客户端请求率。
<code class="language-go">package main import ( "encoding/json" "net/http" "strings" "time" "github.com/go-chi/chi" "golang.org/x/time/rate" ) func main() { r := chi.NewRouter() // Globally limits to 5 requests per second with a burst of 10 r.Use(RateLimiter(rate.Limit(5), 10, 1*time.Second)) // Test route r.Get("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Request successful")) }) http.ListenAndServe(":3000", r) } // RateLimiter middleware func RateLimiter(limit rate.Limit, burst int, waitTime time.Duration) func(next http.Handler) http.Handler { limiterMap := make(map[string]*rate.Limiter) lastRequestMap := make(map[string]time.Time) return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { ip := strings.Split(r.RemoteAddr, ":")[0] limiter, exists := limiterMap[ip] if !exists { limiter = rate.NewLimiter(limit, burst) limiterMap[ip] = limiter } lastRequestTime, lastRequestExists := lastRequestMap[ip] if lastRequestExists && time.Since(lastRequestTime) < waitTime { //Handle exceeding rate limit http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) return } if !limiter.Allow() { http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests) return } lastRequestMap[ip] = time.Now() next.ServeHTTP(w, r) }) } }</code>
超过速率限制会导致429 (Too Many Requests)
错误。
有多种方法可用于识别和限制客户端使用:
基于 IP: 限制来自特定 IP 地址的请求。 简单但在共享网络(NAT)上无效。
基于身份验证令牌: 基于身份验证令牌(JWT、OAuth)跟踪请求。 更细粒度,但需要身份验证。
基于客户端 ID: 使用唯一的客户端 ID(API 密钥)。对于服务集成有效,但如果密钥被泄露,则很容易受到攻击。
每用户会话: 根据唯一会话标识符限制请求。 注重个人用户体验。
基于路由/端点: 将请求限制到特定的高流量端点。 与其他方法结合得很好。
为了简单起见,该示例使用 IP 地址,适用于公共 API 或没有基于令牌的身份验证的应用程序。
速率限制对于应用程序的安全性、稳定性和用户体验至关重要。 此示例演示了使用 Go 和 Chi 的实用且高效的实现。 这是防止滥用和确保公平资源分配的关键技术。
以上是什么是速率限制器以及为什么使用它?的详细内容。更多信息请关注PHP中文网其他相关文章!