网上找到的案例,记录一下

route/init方法中:

var uriLimiters = middleware.NewUriLimiter()
appGroup := g.Group("", middleware.RateLimiter(uriLimiters))

//限流
func RateLimiter(l LimiterIface) gin.HandlerFunc {
return func(c *gin.Context) {
key := l.Key(c) + c.ClientIP()
if bucket, ok := l.GetBucket(key); ok {
count := bucket.TakeAvailable(1)
if count == 0 {
return
}
} else {
l.AddBucketsByUri(key, 3, 100, 100)
c.Next()
}
c.Next()
}
}


中间件具体代码
package middleware

import (
"github.com/gin-gonic/gin"
"github.com/juju/ratelimit"
"strings"
"time"
)

type LimitConfRules struct {
Rules map[string]*LimitOpt `mapstructure:"rules"`
}

type LimitOpt struct {
Interval int64 `mapstructure:"interval"`
Capacity int64 `mapstructure:"capacity"`
Quantum int64 `mapstructure:"quantum"`
}

type LimiterIface interface {
Key(c *gin.Context) string
GetBucket(key string) (*ratelimit.Bucket, bool)
AddBucketsByUri(uri string, fillInterval, capacity, quantum int64) LimiterIface
AddBucketByConf() LimiterIface
}

type Limiter struct {
limiterBuckets map[string]*ratelimit.Bucket
}

type UriLimiter struct {
*Limiter
Rule *LimitConfRules
}

func NewUriLimiter() LimiterIface {
return &UriLimiter{
Limiter: &Limiter{
limiterBuckets: make(map[string]*ratelimit.Bucket),
},
}
}

func (l *UriLimiter) Key(c *gin.Context) string {
uri := c.Request.RequestURI
index := strings.Index(uri, "?")
if index == -1 {
return uri
}
return uri[:index]
}

func (l *UriLimiter) GetBucket(key string) (*ratelimit.Bucket, bool) {
bucket, ok := l.limiterBuckets[key]
return bucket, ok
}

func (l *UriLimiter) AddBucketsByUri(uri string, fillInterval, capacity, quantum int64) LimiterIface {
bucket := ratelimit.NewBucketWithQuantum(time.Second*time.Duration(fillInterval), capacity, quantum)
l.limiterBuckets[uri] = bucket
return l
}

func (l *UriLimiter) getConf() *LimitConfRules {

rule := &LimitConfRules{Rules: map[string]*LimitOpt{
"/": {
Interval: 10, //多长时间添加令牌
Capacity: 1, //令牌桶的容量
Quantum: 1, //到达定时器指定的时间,往桶里面加多少令牌
},
}}

return rule
}

func (l *UriLimiter) AddBucketByConf() LimiterIface {
rule := l.getConf()
for k, v := range rule.Rules {
l.AddBucketsByUri(k, v.Interval, v.Capacity, v.Quantum)
}
return l
}

原文地址:http://www.cnblogs.com/already/p/16888823.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性