Guava:RateLimiter 令牌桶

image.png

  1. // 参数应该为qps 服务器的吞吐量 每秒能处理的请求数
  2. // 每秒只处理2个请求
  3. RateLimiter rateLimiter = RateLimiter.create(0.5);
  4. // 等5秒 获取一个令牌,获取不到报超时
  5. boolean b = rateLimiter.tryAcquire(1,5, TimeUnit.SECONDS);
  6. System.out.println(b);
  7. // 模仿1千万瞬时流量
  8. for (int i = 0; i < 1_0000; i++) {
  9. // 接受请求 以相等于qps的速度 获取
  10. double acquire = rateLimiter.acquire();
  11. System.out.println(acquire);
  12. }

限流算法实现

  1. 常规速率时 每秒放固定的令牌数,以固定的速率旋转,达到平滑输出的效果
  2. 突发流量时 突发流量过少时,一批令牌攒在桶里

Sentinel

限流

系统负载限流

根据系统阈值限制流量

  1. SystemRule rule = new SystemRule();
  2. // 系统阀值
  3. rule.setHighestSystemLoad(3.0);
  4. // Set max average RT(response time) of all passed requests.
  5. rule.setAvgRt(10);
  6. rule.setQps(20);
  7. // 最大线程数
  8. rule.setMaxThread(10);
  9. SystemRuleManager.loadRules(Collections.singletonList(rule));

流控模式

  1. 直接: 当api达到限流条件 直接限流
  2. 关联: 当关联的资源达到阈值 限流自己
  3. 链路:只记录指定链路上的流量,指定资源从入口资源进来的流量,如果达到阈值就进行限流 ,api级别的限流
    流控模式的处理方式:
  • 直接 直接拒绝 告诉用户访问不了
  • warmup 预热冷启动,系统从空闲状态到处理高并发请求的繁忙状态,可能需要过一段时间才能再请求。

如秒杀系统在开启瞬间,会有很多流量上来,很可能把系统打死,预热方式就是为了保护系统,可慢慢的把流量放进来,慢慢的把阈值增长到设置的阈值。

  • 匀速排队 如果qps=1 每1秒只允许一个请求通过

方式会严格控制请求的时间间隔,也就是让请求均匀通过,对应的是漏桶算法。

自定义参数限流

针对用户
  • 每用户qps=2 每个用户1秒内请求不能超过2次
  • 某些用户特殊对待 对特定用户群体制定不同规则的限流

降级

降级规则

等级
  • RT 请求时间 超出RT会被降级
  • 失败率
  • 单位时间内异常次数