限流:
实例:1S 内QPS < 100,按照这个举例
位置:网关GETWAY,服务AOP
场景:
1. 租户:限制某个租户下所有用户的访问次数
2. 用户:某个用户访问次数
3. API(资源):用于保护紧俏资源的访问,优先级最高
4. IP: 限制某个客户端IP
限制单位:可配置最好
1. 1S 累计
2. 3S 累计
限流算法
1. 计数器:
- 方法:count; countLastTime ,limit 统计当前时间<本次截止时间
- 问题:是否控制并发 控制有并发性能瓶颈; 不控制 则有边界问题
2. 滑动时间窗口:
- 逻辑:计算当前访问时刻,向前推1S时间,统计数量。超过阈值 则认为需要限流100;需要记录每次访问的时刻
- 滑动粒度:根据时间戳,向前滑动1S实际是按照ms作为维度,为了实现统计一定时间段内的访问次数,可以按照10ms,100ms为维度。粒度放大就将超出并发放大,比如:100ms 内有100个请求,那么1ms就是1个,边界控制超出去的就是100和1的区别
- 好处:同样有边界和并发问题,当然粒度越小则控制超出的请求越少
3. 漏桶算法:
- 逻辑:既然服务能力是1s处理100个请求,那么服务就按照1S拿100个请求固定速率下发请求
- 控制:漏桶实现(排队长度,等待超时),请求下发器
- 不足:假如是第1ms就来了100个,也会拆分为匀速到1S内消费100个。白白的等了将近1S
4. 令牌桶算法:
- 逻辑:最开始,令牌桶是空的,我们以恒定速率往令牌桶里加入令牌,当桶被装满时,多余的令牌会被丢弃。当请求到来时,会从令牌桶获取令牌,获取成功则请求被放行,获取失败则阻塞或拒绝请求。那么当突发流量来临时,只要令牌桶有足够的令牌,就不会被限流。
- 令牌是一次下发的,不会匀速下发
拒绝策略:超过阈值处理方法
1. 直接丢弃
2. 排队等待(排队等待最长时间,队列长度)
实现:
1. Google Guava 工具包中的 RateLimiter
2. Redis incr命令 expire命令 lua脚本
3. 阿里开源的 Sentinel
参考:
https://cloud.tencent.com/developer/article/2433038
https://zhuanlan.zhihu.com/p/2483538988