一位在传统行业工作了 5 年的程序员。去一个互联网公司面试,被问到一个秒杀的场景题。因为之前完全没接触过分布式相关的项目,单单只是问了限流算法都没有回答不上来,于是向我来求助。
另外,我花了很长时间,准备了一份500页的PDF面试资料文档和一份10W字的Java总结面试题和答案,
1、什么是限流?
所谓限流,就是指限制流量请求的频次。它主要是在高并发情况下,用于保护系统的一种策略,主要是避免在流量高峰导致系统崩溃,造成系统不可用的问题。
实现限流常见的算法4种,分别是计数器限流算法、滑动窗口限流算法、漏桶限流算法、令牌桶限流算法。下面,我给大家详细介绍每种算法的基本原理。
2、限流算法
首先来看第一种,
1、计数器限流算法。
ENTER TITLE
一般用在单一维度的访问频率限制上,比如短信验证码每隔 60s只能发送一次,或者接口调用次数等。它的实现方法很简单,就是每调用一次就加 1,处理结束以后减1。
2、滑动窗口限流算法,
ENTER TITLE
本质上也是一种计数器,只是通过以时间为维度的可滑动窗口设计,来减少了临界值带来的并发超过阈值的问题。每次进行数据统计的时候,只需要统计这 个窗口内每个时间刻度的访问量就可以了。
Spring Cloud 中的熔断框架 Hystrix,以及 Spring Cloud Alibaba 中的Sentinel 都采用滑动窗口来做数据统计。
3、漏桶限流算法。
ENTER TITLE
它是一种恒定速率的限流算法,不管请求量是多少,服务端的处理效率是恒定的。基于 MQ 来实现的生产者消费者模型,其实算是一种漏桶限流算法。
4、令牌桶限流算法。
ENTER TITLE
相对漏桶算法来说,它可以处理突发流量的问题。它的核心思想是,令牌桶以恒定速率去生成令牌保存到令牌桶里面,桶的大小是固定的,令牌桶满了以后就不再生成令牌。
每个客户端请求进来的时候,必须要从令牌桶获得一个令牌才能访问,否则排队等待。在流量低峰的时候,令牌桶会出现堆积,因此当出现瞬时高峰的时候,有足够多的令牌可以获取,因此令牌桶能够允许瞬时流量的处理。
网关层面的限流、或者接口调用的限流,都可以使用令牌桶算法,像 Google 的Guava,和 Redisson 的限流,都用到了令牌桶算法。
我认为,限流的本质是实现系统保护,最终选择什么样的算法,一方面取决于统计的精准度,另一方面考虑限流维度和场景的需求。
以上就是我对限流算法的理解。
最后,我把之前分享的资料全部整理成了文字,希望能够以此来提高各位粉丝的通过率。
我是被编程耽误的文艺Tom,只弹干货不掺水!你们的支持就是我最大的动力!关注我,面试不再难!