rate-limiter
保障服务稳定的三大利器
- 熔断降级
- 服务限流
- 故障模拟
限流的地点:
- Nginx层面的限流
- 业务代码层逻辑上的限流。
实现
计数器、令牌桶、漏桶
计数器
// 伪码: 对于A接口,我们1分钟的访问次数不能超过100个
var limiterKey = getKeyFromEL()
if(`exists limiterKey`){
// 已经存在
var count = get limiterKey;
if(count > 100){
return false;
}
incry limiterKey 1;
return true;
}else{
// 创建新的
`incry limiterKey 1`;
`expire limiterKey 1min`;
return true;
}
问题这个算法很简单,但是有一个十分致命的问题,那就是临界问题,还有会出现突刺现象拒绝大部分请求.
普通限流的
临界问题:
假设有一个恶意用户,他在0:59时,瞬间发送了100个请求,并且1:00又瞬间发送了100个请求,那么其实这个用户在 1秒里面,瞬间发送了200个请求。规定的是1分钟最多100个请求,也就是每秒钟最多1.7个请求,用户通过在时间窗口的重置节点处突发请求, 可以瞬间超过我们的速率限制。用户有可能通过算法的这个漏洞,瞬间压垮我们的应用。
解决方案1: 滑动窗口算法
解决方案 滑动窗口,将时间窗口进行多段划分,当时间到达1:00时,我们的窗口会往右移动一格,每一个格子都有自己独立的计数器counter,此时分析时间窗口内的总请求数量一共是200个,超过了限定的100个,所以此时能够检测出来触发限流
漏桶
// 水(请求)先进桶(阻塞队列),再匀速流出
漏桶算法实现限流可以解决突刺现象,无法应对短时间的突发流量
短时间内流量激增的问题:
令牌-token-桶
// token先匀速进桶,再提取token处理请求