| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 | 
							- package middleware
 
- import (
 
- 	"fmt"
 
- 	"time"
 
- 	"gitee.com/xuyiping_admin/pkg/apierr"
 
- 	"gitee.com/xuyiping_admin/pkg/xerr"
 
- 	"github.com/gin-gonic/gin"
 
- 	limit "github.com/yangxikun/gin-limit-by-key"
 
- 	"golang.org/x/time/rate"
 
- )
 
- // RateLimit limit rate by client ip
 
- // limit 10 qps/client_ip and permit bursts of at most 10 tokens, and the limiter live time duration is 3 minutes
 
- // handle exceed rate limit request
 
- func RateLimit(opts ...*RateLimitOption) gin.HandlerFunc {
 
- 	var opt *RateLimitOption
 
- 	if len(opts) == 0 {
 
- 		opt = defaultRateLimitOption
 
- 	} else {
 
- 		opt = opts[0]
 
- 	}
 
- 	return limit.NewRateLimiter(func(c *gin.Context) string {
 
- 		return fmt.Sprintf("%s-%s", c.ClientIP(), authorization(c))
 
- 	}, func(c *gin.Context) (*rate.Limiter, time.Duration) {
 
- 		return rate.NewLimiter(rate.Every(opt.Interval), opt.Tokens), opt.LiveTime
 
- 	}, func(c *gin.Context) {
 
- 		apierr.AbortBadRequest(c, 429, xerr.Customf("request too many %s", c.ClientIP()))
 
- 	})
 
- }
 
- type RateLimitOption struct {
 
- 	Interval time.Duration
 
- 	Tokens   int
 
- 	LiveTime time.Duration
 
- }
 
- var defaultRateLimitOption = &RateLimitOption{
 
- 	Interval: 100 * time.Millisecond,
 
- 	Tokens:   10,
 
- 	LiveTime: 3 * time.Minute,
 
- }
 
- var testRateLimitOption = &RateLimitOption{
 
- 	Interval: 10 * time.Millisecond,
 
- 	Tokens:   1000,
 
- 	LiveTime: 1 * time.Minute,
 
- }
 
- func RateLimitOptionLow() *RateLimitOption {
 
- 	return &RateLimitOption{
 
- 		Interval: 1 * time.Second,
 
- 		Tokens:   10,
 
- 		LiveTime: 3 * time.Minute,
 
- 	}
 
- }
 
 
  |