Guava:RateLimiter 令牌桶
// 参数应该为qps 服务器的吞吐量 每秒能处理的请求数
// 每秒只处理2个请求
RateLimiter rateLimiter = RateLimiter.create(0.5);
// 等5秒 获取一个令牌,获取不到报超时
boolean b = rateLimiter.tryAcquire(1,5, TimeUnit.SECONDS);
System.out.println(b);
// 模仿1千万瞬时流量
for (int i = 0; i < 1_0000; i++) {
// 接受请求 以相等于qps的速度 获取
double acquire = rateLimiter.acquire();
System.out.println(acquire);
}
限流算法实现
- 常规速率时 每秒放固定的令牌数,以固定的速率旋转,达到平滑输出的效果
- 突发流量时 突发流量过少时,一批令牌攒在桶里
Sentinel
限流
系统负载限流
根据系统阈值限制流量
SystemRule rule = new SystemRule();
// 系统阀值
rule.setHighestSystemLoad(3.0);
// Set max average RT(response time) of all passed requests.
rule.setAvgRt(10);
rule.setQps(20);
// 最大线程数
rule.setMaxThread(10);
SystemRuleManager.loadRules(Collections.singletonList(rule));
流控模式
- 直接: 当api达到限流条件 直接限流
- 关联: 当关联的资源达到阈值 限流自己
- 链路:只记录指定链路上的流量,指定资源从入口资源进来的流量,如果达到阈值就进行限流 ,api级别的限流
流控模式的处理方式:
- 直接 直接拒绝 告诉用户访问不了
- warmup 预热冷启动,系统从空闲状态到处理高并发请求的繁忙状态,可能需要过一段时间才能再请求。
如秒杀系统在开启瞬间,会有很多流量上来,很可能把系统打死,预热方式就是为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。
- 匀速排队 如果qps=1 每1秒只允许一个请求通过
方式会严格控制请求的时间间隔,也就是让请求均匀通过,对应的是漏桶算法。
自定义参数限流
针对用户
- 每用户qps=2 每个用户1秒内请求不能超过2次
- 某些用户特殊对待 对特定用户群体制定不同规则的限流
降级
降级规则
等级
- RT 请求时间 超出RT会被降级
- 失败率
- 单位时间内异常次数