首页 > 后端开发 > Golang > 什么是速率限制器以及为什么使用它?

什么是速率限制器以及为什么使用它?

Mary-Kate Olsen
发布: 2025-01-08 06:36:40
原创
877 人浏览过

Web 系统经常面临短时间内大量客户端请求的挑战。 这可能会使服务器不堪重负,导致速度减慢或失败。 速率限制器通过控制每个客户端的请求频率来优雅地解决这个问题。 它充当看门人的角色,将 API 或服务调用限制在指定的时间窗口内。

为什么要实施速率限制?

速率限制提供了几个重要的好处:

  1. 滥用预防: 缓解过度或恶意请求,例如拒绝服务 (DoS) 攻击,防止系统过载。

  2. 资源管理:确保有效的资源分配,防止一个客户端独占服务器资源并影响其他客户端。

  3. 性能增强:通过防止请求泛滥,即使在高流量负载下也能保持应用程序响应能力。

  4. 改善用户体验:防止用户因请求过多而锁定或性能下降。

  5. 安全加强:通过限制请求率来帮助阻止暴力攻击或利用尝试。

使用 Chi 进行实用的 Go 实现

让我们使用流行的 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)错误。

What is Rate Limiter and Why Use It?

速率限制策略

有多种方法可用于识别和限制客户端使用:

  1. 基于 IP: 限制来自特定 IP 地址的请求。 简单但在共享网络(NAT)上无效。

  2. 基于身份验证令牌: 基于身份验证令牌(JWT、OAuth)跟踪请求。 更细粒度,但需要身份验证。

  3. 基于客户端 ID: 使用唯一的客户端 ID(API 密钥)。对于服务集成有效,但如果密钥被泄露,则很容易受到攻击。

  4. 每用户会话: 根据唯一会话标识符限制请求。 注重个人用户体验。

  5. 基于路由/端点: 将请求限制到特定的高流量端点。 与其他方法结合得很好。

为了简单起见,该示例使用 IP 地址,适用于公共 API 或没有基于令牌的身份验证的应用程序。

结论

速率限制对于应用程序的安全性、稳定性和用户体验至关重要。 此示例演示了使用 Go 和 Chi 的实用且高效的实现。 这是防止滥用和确保公平资源分配的关键技术。

链接

博客文章

示例存储库

以上是什么是速率限制器以及为什么使用它?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板