Api Blocking
- - xiaobaoqiu Blog4.RateLimiter实现限流. 接口限流是保证系统稳定性的三大法宝之一(缓存, 限流, 降级).. 本文使用三种方式实现Api限流, 并提供了一个用Spring实现的Api限流的简单Demo, Demo的git地址: https://github.com/xiaobaoqiu/api-blocking.
接口限流是保证系统稳定性的三大法宝之一(缓存, 限流, 降级).
本文使用三种方式实现Api限流, 并提供了一个用Spring实现的Api限流的简单Demo, Demo的git地址: https://github.com/xiaobaoqiu/api-blocking
其中接口限流配置在文件 blocking-config.properties 中, 内容实例如下:
1 2 3 4 5 6 7 8 9 10 11 | |
里面包含了三种方式来实现限流, 下面将主要审核分别详细介绍三种方式:
1.Redis
2.滑动窗口
3.Guava的RateLimiter
Redis的官网的命令手册的例子就是如何使用 incr 指令实现接口限流.参见官网: https://redis.io/commands/incr/
简单说就是每个请求生成一个key(可以根据IP + 接口url生成, 也可以直接根据接口url生成), value为计数值. 设置过期时间.
需要注意 Redis 的过期策略是混合的:
1.被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key;
2.主动删除:Redis会定期(默认好像是100ms)主动淘汰一批已过期的key;当已用内存超过限定时, 也会触发主动清理策略;
大家都知道TCP中的滑动窗口有调节发送速率的作用.这里是一个类似的想法.
按照我们的配置, 我们期望 duration 时间内最多 limit 个请求, 我们可以想象有一个事件窗口, 其宽度就是 duration, 因为每个请求都有一个时间戳(可以用Long表示), 每次请求过来的时候, 我们只需要校验当前请求为尾端的时间窗口内的请求数目是否满足 limit 需求就行了.
实现很简单, 使用一个环形队列就行.具体参考 demo 代码.
直接使用Guava提供的RateLimiter实现.
RateLimiter的原理参考: http://xiaobaoqiu.github.io/blog/2015/07/02/ratelimiter/