经典面试题——让你设计一个限流的系统怎么做?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典面试题——让你设计一个限流的系统怎么做?相关的知识,希望对你有一定的参考价值。

参考技术A 保障服务稳定的三大利器:熔断降级、服务限流和故障模拟。限流系统是当前很多系统都需要考虑的场景。首先在nginx层面是可以做限流的,除此之外,在微服务层面还是有很多空间可以施展的。

限流的话,主要思路分为 请求数量限制 和 消费能力限制 两类。前者主要是限制一段时间内的总并发数、后者主要是限制消费者的消费能力。

限流算法

限流算法来说,主要包含令牌桶算法、漏桶算法和计数器等。 对于简单的计数器算法 ,通过AtomicLong#incrementAndGet()来进行粗暴的控制,因为容易导致“突刺现象”(比如单位时间1s内的前10ms,已经通过了100个请求,那后面的990ms,只能拒绝), 所以这里不做推荐 。

令牌桶算法

令牌工厂:匀速生成令牌

令牌桶:拥有固定的令牌数

应用者:一次可以申请N个令牌,没有令牌不能进行后续处理。

如果使用Redis来实现的话会比较简单,大概思路如下:

1/ 获取令牌:依靠List的leftPop来获取令牌

Objectresult = redisTemplate.opsForList().leftPop("limit_list");

2/ 向令牌桶添加令牌

redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString());

漏桶算法

漏桶:容量固定

流速:任意

流出水滴:固定速率

滑动窗口

用Redis的list数据结构可以轻而易举的实现该功能:保证每N秒内至多M个请求,缺点就是zset的数据结构会越来越大。实现方式相对也是比较简单的。

1/ 请求进来:UUID生成唯一的value;score用当前的时间戳

redisTemplate.opsForZSet().add("limit",UUID.randomUUID().toString(),currentTime);

2/ 限流:zset的range方法可以统计两个时间戳内的请求,达到限流效果

Integercount = redisTemplate.opsForZSet().rangeByScore("limit", currentTime -

以上是关于经典面试题——让你设计一个限流的系统怎么做?的主要内容,如果未能解决你的问题,请参考以下文章

经典面试题,如何设计一个秒杀系统

Java高频面试题:四种经典限流算法,有哪四种?

Java高频面试题:四种经典限流算法,有哪四种?

面试必备:4种经典限流算法讲解

软件测试工程师经典面试题汇总

阿里巴巴历年经典面试题汇总:Java岗