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

速率限制特定端点

速率限制特定端点

Go
FFIVE 2023-03-15 14:24:03
我是 GoLang 的新手,正在开发我的第一个 API。我有两个端点,我只想对其中一个端点进行速率限制。我找到了一个有用的教程来帮助我入门,我的方法基于教程,认识到这种方法将限制我的两个端点:var limiter = rate.NewLimiter(rate.Every((1*time.Hour)/3), 1)func limit(next http.Handler) http.Handler {    return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {        if limiter.Allow() == false {            http.Error(res, http.StatusText(429), http.StatusTooManyRequests)            return        }        next.ServeHTTP(res, req)    })}func main() {    mux := http.NewServeMux()    mux.HandleFunc("/", createNewToken)    mux.HandleFunc("/notify", sendPushNotificationToAllTokens)    log.Fatal(http.ListenAndServeTLS(":5050", "localhost.crt", "localhost.key", limit(mux)))}我研究了http.Handle 和 http.HandleFunc之间的区别,天真地认为我可以http.HandleFunc 替代http.Handle. 这种方法是完全有缺陷的,因为永远不会执行中包含的逻辑HandlerFunc:var limiter = rate.NewLimiter(rate.Every(1*time.Hour/3), 1)func limit(next http.HandlerFunc) http.HandlerFunc {    return func(res http.ResponseWriter, req *http.Request) {        if limiter.Allow() == false {            http.Error(res, http.StatusText(429), http.StatusTooManyRequests)            return        }        next.ServeHTTP(res, req)    }}func main() {    //mux := http.NewServeMux()    http.HandleFunc("/", createNewToken)    http.HandleFunc("/notify", sendPushNotificationToAllTokens)    // attempt to only rate limit the /notify endpoint     log.Fatal(http.ListenAndServeTLS(":5050", "localhost.crt", "localhost.key", limit(sendPushNotificationToAllTokens)))谁能解释为什么这不起作用,以及我如何解决这个问题以仅对特定端点进行速率限制?
查看完整描述

1 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

使用 plainhttp.Handler和 a之间的区别http.HanlderFunc在这里并不重要。http.HandleFunc只是一种将常规函数转换为 a 的方法http.Handler- 它本质上与原始版本的limit.


您对limit两者的实现看起来都不错;可能第二个更好,因为它更简单。相反,问题出在main. 当您调用http.ListenAndServeTLS并为最终参数提供值时,它会请求仅将您作为最终参数传入的处理程序用作根请求处理程序。除非您作为最后一个参数传入,否则对http.Handle()或的任何调用都会被忽略。http.HandleFunc()nil


您要做的是应用于limit您要限制的特定处理程序。为此,您有两种选择。ServeMux首先,您可以在第一个代码片段中使用like:


func main() {

    mux := http.NewServeMux()

    mux.HandleFunc("/", createNewToken)

    // Limit only the handler for "/notify".

    mux.HandleFunc("/notify", limit(sendPushNotificationToAllTokens))


    // Don't limit the whole mux.

    log.Fatal(http.ListenAndServeTLS(":5050", "localhost.crt", "localhost.key", mux))

}

nil或者,您可以做一些更像您的第二个代码片段的事情,但将最后一个参数传递给http.ListenAndServeTLS以便http.ServeMux使用默认值,这意味着http.HandleFunc()将尊重对的调用:


func main() {

    http.HandleFunc("/", createNewToken)

    // Limit only the handler for "/notify".

    http.HandleFunc("/notify", limit(sendPushNotificationToAllTokens))


    // Pass in nil here so that http.DefaultServeMux is used.

    log.Fatal(http.ListenAndServeTLS(":5050", "localhost.crt", "localhost.key", nil))

}

对于一个简单的应用程序,第一种方法可能没问题。对于更复杂的事情,我推荐后一种方法,因为如果您打开多个服务器或做其他更复杂的事情,它就会起作用。


查看完整回答
反对 回复 2023-03-15
  • 1 回答
  • 0 关注
  • 70 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

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

帮助反馈 APP下载

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

公众号

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