为了账号安全,请及时绑定邮箱和手机立即绑定

golang.org/x/time/rate api 请求的速率限制

golang.org/x/time/rate api 请求的速率限制

Go
MMTTMM 2022-05-23 16:21:40
我已经创建了一个函数,用于在一天内限制 50 个 API 登录请求。变量限制 = 50package middlewareimport (    "log"    "net"    "net/http"    "sync"    "time"    "golang.org/x/time/rate")// Create a custom request struct which holds the rate limiter for each// visitor and the last time that the request was seen.type request struct {    limiter  *rate.Limiter    lastSeen time.Time}// Change the the map to hold values of the type request.// defaultTime using 3 minutesvar requests = make(map[string]*request)var mu sync.Mutexfunc getRequest(ip string, limit int) *rate.Limiter {    mu.Lock()    defer mu.Unlock()    v, exists := requests[ip]    if !exists {        limiter := rate.NewLimiter(1, limit)        requests[ip] = &request{limiter, time.Now()}        return limiter    }    // Update the last seen time for the visitor.    v.lastSeen = time.Now()    return v.limiter}func throttle(next http.Handler, limit int) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        ip, _, err := net.SplitHostPort(r.RemoteAddr)        if err != nil {            log.Println(err.Error())            http.Error(w, "Internal Server Error", http.StatusInternalServerError)            return        }        limiter := getRequest(ip, limit)        fmt.Println(limiter.Allow())        if limiter.Allow() == false {            http.Error(w, http.StatusText(http.StatusTooManyRequests), http.StatusTooManyRequests)            return        }        next.ServeHTTP(w, r)    })}这是正确的吗?因为当我尝试它时,它仍然通过。功能限制不起作用。我怀疑 NewLimiter() limiter := rate.NewLimiter(1, limit)这是否意味着一个用户每天只能请求登录 50 个请求?(我已经阅读了文档,但我不明白。)
查看完整描述

2 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

从费率文档:


func NewLimiter(r Limit, b int) *Limiter

NewLimiter 返回一个新的限制器,它允许事件的速率达到 r 并允许最多 b 个令牌的突发。


所以第一个参数是速率限制,而不是第二个。Burst 是您希望允许发生的请求数量快于速率限制 - 通常使用一个值1来禁止突发,任何更高的值都会在常规速率限制启动之前允许此数量的请求。无论如何.. .


要根据rate.Limit您的需要创建,您可以使用辅助函数rate.Every():


rt := rate.Every(24*time.Hour / 50)


limiter := rate.NewLimiter(rt, 1)


查看完整回答
反对 回复 2022-05-23
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

NewLimited(1, 50)表示 1 个请求/秒,最多 50 个请求。它是一个令牌桶,这意味着有 50 个令牌,每个接受的 API 调用使用一个令牌,并且令牌以给定的速率重新生成,最多burst. 您的代码正在为每个 IP 地址创建一个限制器,因此这是每个 IP 地址的限制(我猜您将其近似为一个 IP 地址是一个用户)。

如果您在单个持久服务器上运行,并且服务器和代码永远不会重新启动,那么您可以通过指定速率50 / (3600*24)和 50 的突发来获得每个用户每天 50 个请求。(注意:3600*24是一天中的秒数)。但是您正在使用的速率限制包并不是为这种粗略的速率限制而设计的(按每天请求的顺序)——它旨在防止服务器在短期内因流量过大而过载(按每秒请求的顺序) )。

您可能需要一个可与数据库或类似工具一起使用的速率限制器(可能使用令牌桶方案,因为这可以有效地实现)。可能在某个地方有一个包裹,但我不知道我的头顶有一个。


查看完整回答
反对 回复 2022-05-23
  • 2 回答
  • 0 关注
  • 279 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号