分布式限流方案

限流是常见的应用保护方案

常见限流方案

  1. 基于IP地址和基于服务器的访问请求限流。抵挡部分易识别的DDOS攻击,主要对request 请求头做解析判断
  2. QPS、并发量(连接数)限流,如Tomcat,就有最大连接数、最大请求数的设置。
  3. 下行带宽速率限制

限流算法

1. 令牌桶算法

单位时间内往一定容量的桶里存入令牌,令牌消耗完则时间内的请求被拒绝。 放入令牌的速度是恒定的,但是消费令牌的速度是不定的。也就是可能在流量激增的时候把令牌都消费完了导致无法访问。

基于队列实现,用队列存储令牌,每来一个请求就从队列取出一个令牌,令牌为空则拒绝请求。另一个线程稳定向队列里放入令牌,直到队列满。

2. 漏桶算法

限流更加平滑,流速是稳定的,超过流速则拒绝。消费稳定,放入流量不定。导致瞬间的流量并不会全部都消费,而是挡出去了一部分,后续新流量还是能恒定进入。

可以用FIFO队列模拟手痛,队列的容量就是水桶的最大大小,超过队列容量就拒绝,

3. 计数器算法

计数器算法是在一定时间内记录访问的次数,过了间隔就清零。比如一分钟限定能有10个访问,超过十个,拒绝访问,到了下一分钟又有10个可以访问。

单机限流可以使用内存,但是分布式集群的情况就需要引入redis。但是不能细粒度控制流量在定时区间内的平滑性,依然会有毛刺。如临界点就把两个相连区间的限定给用完了。

4. 滑动窗口算法

TCP著名的滑动窗口,滑动窗口弥补了计数器算法的不足,将大区间分成独立的小区间,只统计独立区间(黑框)的请求数量,超出独立格子的数量就会被丢弃。 我们在每一秒内有5个用户访问,第5秒内有10个用户访问,那么在0到5秒这个时间窗口内访问量就是15。如果我们的接口设置了时间窗口内访问上限是20,那么当时间到第六秒的时候,这个时间窗口内的计数总和就变成了10,因为1秒的格子已经退出了时间窗口,因此在第六秒内可以接收的访问量就是20-10=10个。

总结

|算法|优点|缺点| |令牌桶|预存一定量令牌,允许突发流量|后台系统压力大| |漏桶|对于后台系统不会有突发流量|丧失对于突发流量的处理能力| |计数器算法|简单|有临界问题,不平滑| |滑动窗口算法|优化计数器算法平滑问题|更大的内存开销|

限流层

从接入层到应用层,对应不同的部件使用不同的方式进行限流,限流的要求也不同。

  1. 接入层: Nginx、Openresty
  2. 应用网关层:SpringGateway、zuul
  3. 应用层:根据业务情况,由应用层自行编写限流。经典就是游戏排队,需要xxx分钟进入服务器。

限流实战

Guava Ratelimiter

流量预热,在大促或者大流量场景预测下,将令牌桶的桶容量增大以增强突发流量应对能力。 主要猎是SmoothWarmingUp,他是SmoothRateLimiter的内部类。重点是doSetRate方法。

Redis+lua

Spring Gateway

默认提供了Lua+Redis的限流服务,当Redis服务不可用时,Gateway就直接将所有请求做放行处理。

上WAF高防

Sentinel

流行的第三方限流组件,独立部署。应用引入依赖包,配置Sentinel的连接。实现Sentinel控制应用服务接口级别的限流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章