Gin 系列讲座: Saas系统, Gin+Jwt+casbin RestFul Api 后端一战到底 5: RateLimit 访问限速
限速中间件
前面到文章介绍了,gin框架如何加中间件。 还画了个草图。 描述未拨洋葱。。 就是在http request 和下一个处理之间加上一个层
为什么限速
客户端访问 ,很多种情况需要限速。 比如秒杀,高峰期, 防止恶意访问。 还有需要限速购买访问等等很多中情况。都需要限速
如何限速
利用gin 中间件。 如下代码。 可有采用redis 缓存,或者其他替代方案。 来限制 科幻请求的频率。 超过我们设定的频率,则不错了。就是这么简单。
// RateLimiterMiddleware 请求频率限制中间件
func RateLimiterMiddleware(skipper ...SkipperFunc) gin.HandlerFunc {
cfg := config.GetGlobalConfig().RateLimiter
if !cfg.Enable {
return func(c *gin.Context) {
c.Next()
}
}
rc := config.GetGlobalConfig().Redis
ring := redis.NewRing(&redis.RingOptions{
Addrs: map[string]string{
"server1": rc.Addr,
},
Password: rc.Password,
DB: cfg.RedisDB,
})
limiter := redis_rate.NewLimiter(ring)
limiter.Fallback = rate.NewLimiter(rate.Inf, 0)
return func(c *gin.Context) {
if (len(skipper) > 0 && skipper[0](c)) || limiter == nil {
c.Next()
return
}
userID := ginplus.GetUserID(c)
if userID == "" {
c.Next()
return
}
limit := cfg.Count
rate, delay, allowed := limiter.AllowMinute(userID, limit)
if !allowed {
h := c.Writer.Header()
h.Set("X-RateLimit-Limit", strconv.FormatInt(limit, 10))
h.Set("X-RateLimit-Remaining", strconv.FormatInt(limit-rate, 10))
delaySec := int64(delay / time.Second)
h.Set("X-RateLimit-Delay", strconv.FormatInt(delaySec, 10))
ginplus.ResError(c, errors.ErrTooManyRequests)
return
}
c.Next()
}
}
一个小问题, 我们还有什么功能能加到中间件上去呢?
大家可有想想。自己想的,理解的才是真的学到到。