引言
本节主要学习下两种常用的单机限流思想,分别是漏桶算法和令牌桶算法。此外,还将给出使用 Python 及 Go 语言实现,便于加深理解。当然,现实中肯定不能直接用下面的代码。实际应用时,我们不大可能在单机执行限流,下面的实现也并非线程或 goroutine 安全的。
实际限流可以考虑在 Nginx 层对请求限流,或者如果真的要自己在业务方实现一套限流策略的话,可以考虑基于 Redis 实现分布式限流策略。并且在实际应用中,可能还会基于不同的维度进行限流,如用户 id,请求 IP 等,实际应用需要考虑的东西更多。
漏桶算法
可以把请求当作水流,水流全部进入有限大小的水缸,同时水缸会按照固定的速率漏水。当水流湍急,水缸漏水太慢的话,会得知水缸积水,直到溢出(此时拒绝服务)。
特点
- 实现起来很简单,并且能够以比较恒定的速率服务请求
- 缺点是无法应对突发流量,很容易导致溢出
实现
Python
1 | class LeakyBucketRateLimiter(object): |
Go
1 | type LeakyBucketRateLimiter struct { |
令牌桶算法
同样想象我们有一个桶,专门存放令牌,会以恒定的速率生成令牌,并将其放入桶中。每当有请求过来时,需要先从桶中取到一个或多个令牌,如果获取成功,则为请求提供服务,否则拒绝服务。
特点
- 实现同样是很简单
- 可以应对突发流量,面对瞬间大流量,可以在短时间内获得大量令牌,且生产令牌毫不费力
- 可以做流量整形
实现
Python
1 | class TokenBucketRateLimiter(object): |
Go
1 | type TokenBucketRateLimiter struct { |