猿问

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

我已经创建了一个函数,用于在一天内限制 50 个 API 登录请求。


变量限制 = 50


package middleware


import (

    "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 minutes

var requests = make(map[string]*request)

var mu sync.Mutex


func 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 个请求?(我已经阅读了文档,但我不明白。)


MMTTMM
浏览 281回答 2
2回答

莫回无

从费率文档:func NewLimiter(r Limit, b int) *LimiterNewLimiter 返回一个新的限制器,它允许事件的速率达到 r 并允许最多 b 个令牌的突发。所以第一个参数是速率限制,而不是第二个。Burst 是您希望允许发生的请求数量快于速率限制 - 通常使用一个值1来禁止突发,任何更高的值都会在常规速率限制启动之前允许此数量的请求。无论如何.. .要根据rate.Limit您的需要创建,您可以使用辅助函数rate.Every():rt := rate.Every(24*time.Hour / 50)limiter := rate.NewLimiter(rt, 1)

叮当猫咪

NewLimited(1, 50)表示 1 个请求/秒,最多 50 个请求。它是一个令牌桶,这意味着有 50 个令牌,每个接受的 API 调用使用一个令牌,并且令牌以给定的速率重新生成,最多burst. 您的代码正在为每个 IP 地址创建一个限制器,因此这是每个 IP 地址的限制(我猜您将其近似为一个 IP 地址是一个用户)。如果您在单个持久服务器上运行,并且服务器和代码永远不会重新启动,那么您可以通过指定速率50 / (3600*24)和 50 的突发来获得每个用户每天 50 个请求。(注意:3600*24是一天中的秒数)。但是您正在使用的速率限制包并不是为这种粗略的速率限制而设计的(按每天请求的顺序)——它旨在防止服务器在短期内因流量过大而过载(按每秒请求的顺序) )。您可能需要一个可与数据库或类似工具一起使用的速率限制器(可能使用令牌桶方案,因为这可以有效地实现)。可能在某个地方有一个包裹,但我不知道我的头顶有一个。
随时随地看视频慕课网APP

相关分类

Go
我要回答