Gin Series of lectures: Saas Systems, Gin+Jwt+ Casbin RestFul Api Backend Battle to the End 5: RateLimit Access Limit
Speed limiting middleware
The previous article introduced how the GIN framework can be combined with middleware. I even made a sketch. Describe unplucked Onions. Add a layer between the HTTP request and the next processing
Why the speed limit
Client access requires speed limiting in many cases. Like seckill, peak hours, malicious access prevention. There is also the need for speed limit purchase access and many other cases. You need speed limits
How the speed limit
Leverage gin middleware. The following code. You can use redis cache, or other alternatives. To limit the frequency of sci-fi requests. Beyond the frequency we set, that’s good. It’s that simple.
// RateLimiterMiddleware requests frequency limiting middleware
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()
}
}
Copy the code
Quick question, what else can we add to the middleware?
You have to think about it. What you think and understand is what you really learn.