限流
限流又称为流量控制(流控),通常是指限制到达系统的并发请求数。
限流虽然会影响部分用户的使用体验,但是能确保系统的稳定性,不至于让所有用户都无法使用。
限流的一些应用:
- 防止恶意攻击:通过限制来自同一IP或同一用户的请求数量,可以有效地防止恶意攻击和爬虫采集。
- 控制资源使用:对于一些需要付费使用的服务,可以通过限流来控制资源的消耗,避免资源浪费。
- 用户请求限制:每个用户在一定时间内针对某个请求只能发起有限次数的请求,以控制用户行为。
常用的限流策略
漏桶
漏桶限流策略是一种常用的流量控制算法,它通过限制单位时间内处理的请求数量来达到限流的目的。以下是漏桶限流策略的主要特点和工作原理:
- 基本概念:漏桶算法将请求比作水,系统比作桶。水(请求)以任意速率流入桶中,而桶以固定速率“漏”出水,即以固定速率处理请求。
- 固定速率:漏桶算法规定了桶的漏出速率,即系统能够处理请求的最大速率。这个速率是固定的,不随外部请求的频率变化。
- 桶的容量:桶的容量决定了漏桶算法能够容纳的请求数量。如果桶满了,新的请求将被拒绝或者排队等待。
- 请求处理:当请求到达时,如果桶中有足够的空间(即桶未满),请求被接受并放入桶中;如果桶已满,请求将被丢弃或排队。
- 平滑流量:漏桶算法可以平滑突发流量,因为它强制请求以固定的速率被处理,而不是按照它们到达的速率。
- 适用场景:漏桶算法适用于需要平滑流量的场景,例如在网络通信、API网关等场景中,它可以保护后端服务不受突发流量的影响。
- 缺点:漏桶算法的主要缺点是它不能处理突发流量,因为它强制所有请求以固定速率被处理,即使系统有能力在某一时刻处理更多的请求。
- 与其他算法的比较:与令牌桶算法相比,漏桶算法缺乏处理突发流量的能力。令牌桶算法允许在桶未满的情况下,以高于固定速率处理请求。
- 实现工具:许多开源框架和中间件,如Redis、Nginx等,提供了基于漏桶算法的限流功能,可以方便地集成到系统中。
令牌漏桶
令牌桶限流策略是一种流行的流量控制算法,它允许在一定时间内以一定的速率处理请求,同时也能够处理突发流量。以下是令牌桶限流策略的详细解释:
基本概念
- 令牌桶:一个虚拟的桶,用来存放令牌。每个令牌代表处理一个请求的能力。
- 令牌生成速率:令牌以固定速率生成,这个速率决定了系统能够处理请求的最大频率。
- 桶的容量:桶的大小限制了最多可以存放的令牌数量。当桶满了之后,新生成的令牌会被丢弃。
工作原理
- 令牌生成:系统以固定的速率向桶中添加令牌。
- 请求处理:当一个请求到达时,它会尝试从桶中取出一个令牌。如果桶中有令牌,请求会被处理,并且桶中的令牌数量减少一个。
- 桶满丢弃:如果桶已经满了,新生成的令牌会被丢弃,保证桶中的令牌数量不会超过桶的容量。
- 突发流量处理:如果桶中有足够的令牌,系统可以一次性处理多个并发请求,从而应对突发流量。
- 请求拒绝:如果桶中没有令牌,新到达的请求将被拒绝或排队等待,直到桶中有可用的令牌。
在Gin中使用令牌桶做限流中间件
func RatelimitMiddleware(fillInterval time.Duration, capacity int64) gin.HandlerFunc {
bucket := ratelimit.NewBucket(fillInterval, capacity)
return func(c *gin.Context) {
// 如果取不到令牌就中断本次请求返回 rate limit...
if bucket.TakeAvailable(1) < 1 {
c.String(http.StatusOK, "rate limit...")
c.Abort()
return
}
c.Next()
}
}