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

本文深入探讨了如何通过熔断降级机制防止系统崩溃,以及在Nginx和微服务层面实施限流策略,重点讲解了令牌桶算法、漏桶算法和计数器算法。实例展示了如何利用Redis实现限流,包括使用list和zset数据结构。关键概念包括消费能力限制、滑动窗口限流和Redis操作细节。
摘要由CSDN通过智能技术生成

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

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

限流算法

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

令牌桶算法

令牌工厂:匀速生成令牌

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

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

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

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

Object result = 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方法可以统计两个时间戳内的请求,达到限流效果

Integer count = redisTemplate.opsForZSet().rangeByScore("limit", currentTime -
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值