美文网首页Java
经典面试题——让你设计一个限流的系统怎么做?

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

作者: 一只程序猿哟 | 来源:发表于2022-04-02 13:58 被阅读0次

    保障服务稳定的三大利器:熔断降级、服务限流和故障模拟。限流系统是当前很多系统都需要考虑的场景。首先在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 -

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/mlutsrtx.html