应用场景为避免并发量忽然增高时,服务器无奈接受,保障了QPS的上限值。
次要分为漏桶和令牌桶:
漏桶是指咱们有一个始终装满了水的桶,每过固定的一段时间即向外漏一滴水。如果你接到了这滴水,那么你就能够持续服务申请,如果没有接到,那么就须要期待下一滴水。
令牌桶则是指匀速向桶中增加令牌,服务申请时须要从桶中获取令牌,令牌的数目能够依照须要耗费的资源进行相应的调整。如果没有令牌,能够抉择期待,或者放弃。
package mainimport ( "net/http" "time" "github.com/gin-gonic/gin" "github.com/juju/ratelimit")func RateLimitMiddleware(fillInterval time.Duration, cap, quantum int64) gin.HandlerFunc { bucket := ratelimit.NewBucketWithQuantum(fillInterval, cap, quantum) return func(c *gin.Context) { if bucket.TakeAvailable(1) < 1 { c.String(http.StatusForbidden, "rate limit...") c.Abort() return } c.Next() }}func main() { r := gin.Default() gin.ForceConsoleColor() r.Use(RateLimitMiddleware(time.Second, 100, 100)) //初始100,每秒放出100 r.GET("/", func(c *gin.Context) { c.String(http.StatusOK, "golang ~") }) r.Run(":8080")}
1、认的令牌桶,fillInterval 指每过多长时间向桶里放一个令牌,capacity 是桶的容量,超过桶容量的局部会被间接抛弃。桶初始是满的
func NewBucket(fillInterval time.Duration, capacity int64) *Bucket
2、和一般的 NewBucket() 的区别是,每次向桶中放令牌时,是放 quantum 个令牌,而不是一个令牌。
func NewBucketWithQuantum(fillInterval time.Duration, capacity, quantum int64) *Bucket
3、依照提供的比例,每秒钟填充令牌数。例如 capacity 是100,而 rate 是 0.1,那么每秒会填充10个令牌。
func NewBucketWithRate(rate float64, capacity int64) *Bucket