34操作流量(限流算法)

300 阅读4分钟

1.什么是限流

  • 针对非核心业务可以使用熔断和降级,毕竟不影响主流程服务
  • 核心业务出现超出流量,使用限流,提升系统鲁棒性
  • 重点掌握:限流算法

\

  • 什么是限流?

    • 通过限制到达系统并发请求的数量,保证系统能够与响应部分用户请求

    • 超过限制的请求,会拒绝服务保证系统的可用性

    • 一般部署在服务的入口层

      • API网关
      • RPC客户端
  •  生活中的限流

    • 旅游景区限流
    • 地铁
  • TCP的滑动窗口

    • 接收方根据处理能力,限制发送方的数据量
    • 接收方处理速度快,窗口就大(不限流)
    • 接收方处理速度慢,窗口就小(限流)

  • 微服务下可以从什么方面进行流量限制

    • 系统每分钟处理的请求数
    • 接口每分钟处理的请求数
    • 单个用户|ip每分钟发送请求的数量
    • appkey的访问接口速率

2.限流算法

限流就需要限制一段时间内向系统发起总体的请求量

2.1固定窗口

暴力+直观解法:统计一分钟的请求次数,超出的请求数直接返回错误

下一分钟重置计数器

private AtomicInteger counter; //定时清零 
ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor(); timer.scheduleAtFixedRate(new Runnable(){     
@Override     
public void run() {         
counter.set(0);     } }, 0, 1, TimeUnit.SECONDS);   
//是否限流 
public boolena isRateLimit() { return counter.incrementAndGet() >= allowedLimit;}   
//计数器加1  
counter.inc()

缺点:

无法限制短时间之内的集中流量(处理突发情况不够圆滑)

假如我们需要限制每秒钟只能处理 10 次请求,如果前一秒钟产生了 10 次请求

这 10 次请求全部集中在最后的 10 毫秒中,而下一秒钟的前 10 毫秒也产生了 10 次请求

那么在这 20 毫秒中就产生了 20 次请求,超过了限流的阈值

但是因为这 20 次请求分布在两个时间窗口内,所以没有触发限流,这就造成了限流的策略并没有生效。

2.2滑动窗口

基于固定窗口的缺点,使用滑动窗口

将时间的窗口划分为多个小窗口,每个小窗口中都有单独的请求计数

虽然解决了固定窗口不能解决突发流量的限制,但是处理还是不够平滑,实际应用中一般使用漏桶算法和令牌桶算法

3.漏桶算法

在流量产生端和接收端增加一个漏桶,流量会进入和暂存到漏桶中,漏桶出口会按照固定速率输出到接收端

保证了所有流量平滑到达服务端

一般使用消息队列(对流量进行削峰填谷)

\

4.令牌桶算法

  • 在一秒内限制访问次数为N次,没隔1/N的时间,往桶内放入一个令牌

  • 新的请求每次获取一个令牌,如果没有令牌则看策略

    • 拒绝服务
    • 阻塞等待
  • 通过定期放入令牌,是的避免损失流量高峰(类似消息队列的削峰填谷)

  • 优化:可以预置一些令牌在其中

  • 相比于漏桶算法更适合互联网环境,不需要向漏桶缓缓存请求

  • 实现

    • 单机:使用一个数值即可
    • 分布式:使用redis,可以获取一批令牌

5.总结

  • 限流是一种和常见的保护策略,可以针对不同维度进行限流

  • 基于时间窗口维度有固定算法和滑动窗口算法,但是处理都不够平滑

  • 令牌桶算法和漏桶算法则能够塑形流量,让流量更加平滑,但是令牌桶算法能够应对一定的突发流量,所以在实际项目中应用更多(削峰填谷)\

  • 限流策略是微服务治理中的标配策略,只是你很难在实际中确认限流的阈值是多少,设置的小了容易误伤正常的请求,设置的大了则达不到限流的目的\

    • 需要动态调整\

    • 根据压测结果进行调整