使用场景为防止并发量突然增高时,服务器无法承受,保证了QPS的上限值。
主要分为漏桶和令牌桶:
漏桶是指我们有一个一直装满了水的桶,每过固定的一段时间即向外漏一滴水。如果你接到了这滴水,那么你就可以继续服务请求,如果没有接到,那么就需要等待下一滴水。
令牌桶则是指匀速向桶中添加令牌,服务请求时需要从桶中获取令牌,令牌的数目可以按照需要消耗的资源进行相应的调整。如果没有令牌,可以选择等待,或者放弃。
package main
import (
"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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。