令牌桶限流
令牌桶限流算法基于令牌桶的概念,用于控制请求的流量。令牌桶中保存着固定数量的令牌,每个令牌代表一个请求。当一个请求到来时,如果令牌桶中有足够的令牌,则允许该请求通过并消耗一个令牌,否则拒绝该请求。 令牌桶限流算法的实现思路如下: 1. 初始化一个令牌桶,包含初始令牌数量以及令牌放入速率。 2. 当一个请求到来时,检查令牌桶中是否有足够的令牌可供消耗。 3. 如果有足够的令牌,则允许该请求通过,并将令牌桶中的令牌数减少。 4. 如果没有足够的令牌,则拒绝该请求或者将其加入队列等待。 在Go语言中,可以使用`golang.org/x/time/rate`包来实现令牌桶限流。该包提供了`limiter.Limiter`类型,可以方便地控制请求的速率。示例代码:
```go package main import ( "fmt" "time" "golang.org/x/time/rate" ) func main() { l := rate.NewLimiter(10, 1) // 每秒放入10个令牌,允许的最大并发数为10 for i := 0; i < 20; i++ { if l.Allow() { // 判断是否允许通过 fmt.Println("Request", i, "allowed at", time.Now()) } else { fmt.Println("Request", i, "rejected at", time.Now()) } time.Sleep(time.Second) } } ``` 上述示例中,我们创建了一个限制每秒放入10个令牌的`Limiter`,并模拟了20个请求的到来。在每个请求到来时,通过`l.Allow()`方法来判断是否允许通过。运行结果如下: ``` Request 0 allowed at 2019-12-01 14:15:00.000 Request 1 allowed at 2019-12-01 14:15:01.000 ... Request 10 rejected at 2019-12-01 14:15:10.000 Request 11 allowed at 2019-12-01 14:15:11.000 ... ``` 从结果中可以看出,前10个请求都被允许通过,而第11个请求因为令牌桶已满被拒绝。漏斗限流
漏斗限流算法基于漏斗的概念,用于控制请求的流量。漏斗接受请求并按指定的速率处理,如果请求太快,漏斗就会溢出并被丢弃。 漏斗限流算法的实现思路如下: 1. 初始化一个容量为B的漏斗,以及一个剩余空间大小为r的变量。 2. 当一个请求到来时,检查漏斗中是否有足够的剩余空间,即r是否大于请求的大小。 3. 如果有足够的剩余空间,则允许该请求通过,并将剩余空间减少。 4. 如果没有足够的剩余空间,则拒绝该请求或者将其加入队列等待,并根据漏斗的速率来决定何时释放剩余空间。 在Go语言中,可以使用`github.com/oooldking/log@v1.0.0/leakybucket`包来实现漏斗限流。该包提供了`leakybucket.NewLeakyBucket`函数用于创建漏斗限流器。示例代码:
```go package main import ( "fmt" "time" "github.com/oooldking/log/leakybucket" ) func main() { bucket := leakybucket.NewLeakyBucket(10, 2) // 容量为10,每秒放入2个令牌的漏斗 for i := 0; i < 20; i++ { if bucket.Acquire(1) { // 剩余空间是否大于1 fmt.Println("Request", i, "allowed at", time.Now()) } else { fmt.Println("Request", i, "rejected at", time.Now()) } time.Sleep(time.Second) } } ``` 上述示例中,我们创建了一个容量为10,每秒放入2个令牌的漏斗,并模拟了20个请求的到来。在每个请求到来时,通过`bucket.Acquire(1)`方法来判断是否允许通过。运行结果如下: ``` Request 0 allowed at 2019-12-01 14:15:00.000 Request 1 allowed at 2019-12-01 14:15:01.000 ... Request 9 rejected at 2019-12-01 14:15:09.000 Request 10 allowed at 2019-12-01 14:15:10.000 ... ``` 从结果中可以看出,前10个请求都被允许通过,而第11个请求因为漏斗已满被拒绝。