对接口进行限流?

在高并发的情况下,我们可以把消息放入队列,在从队列消费,达到限流的目的。但这里说的限流指的是当我们请求其他服务器接口,防止高并发下把对面服务器压垮,于是对我们要求每秒限制在100QPS。

如果使用springCloud可以用hystrix限流,如果使用springCloud-alibaba可以使用sentinal实现限流,那么如果不依赖组件,如何实现接口限流呢?

限流的策略有:拒绝服务,等待排队,服务降级。

最简单拒绝服务可以直接返回异常抛出,请用户稍后再试。

但对一些重要的接口,比如下单,秒杀等,我们不希望用户请求太快,也不希望拒绝失败,这种可以放到队列。

那么服务降级则是触发限制条件,直接返回兜底数据,比如查询库存默认返回有库存。

  • 计数器限流(固定窗口限流)

我们可以通过AtomicLong来限制发送的数量,比如一分钟之内发送60条数据,那么平均每秒发送1条数据,当超过一分钟的时候,再把计数器归零,如果没有超过一分钟,则大于60的时候,不允许继续访问接口。

但这样有一个致命缺点,如果有恶意用户进行访问,在59s的时候发送60条,在1min01s的时候发送60条,那么在2s之内就处理了120条数据,这时候很有可能把服务器压垮而且这种情况下,剩余的59s都属于空闲状态,也是不合理的。。

说到底,这是颗粒度太大,不够精细导致的,那么如何解决呢?

  • 滑动窗口

先定义一个key,在通过redis管道实现滑动窗口判断是否符合限流行数。

对接口进行限流?_第1张图片

 对接口进行限流?_第2张图片

 

管道里放入的是这个滑动窗口的数据量,每次新增都会删除超过时间的元素,而且限流最大请求次数是灵活的。

  • 漏桶算法

算法实现是,我们有一个固定容量的桶,有水流进来,也有水流出去,我们可以控制水流出的速率和,对于进来的水,我们无法控制进来多少和速率,当桶满的时候,则进入拒绝策略。

我们只要把算法里的水换成用户请求。

这个算法也有缺陷,因为当拒绝的时候,会丢弃,而且在高并发的情况下,处理效率不高,于是有了下面广泛使用的令牌漏桶算法。

  • 令牌漏桶算法

系统会维护一个令牌桶,以恒定的速度往里面放令牌,这时候如果有请求,则先看要有没有令牌,没有则限制请求。

对接口进行限流?_第3张图片

 

你可能感兴趣的:(java,spring,boot,分布式)