• Java中常见的限流算法讲解以及实现思路


    计数器算法

    通俗一点的理解就是在给定时间内,允许n个请求通过,第n+1个请求则抛弃。

    例子:比如设置1秒5次。那么第一秒内的第六个请求就抛弃,第二秒内,又可以进入五个请求。

    使用时注意这么一种情况(我觉得只有适不适合的场景,算不算缺点就看你的理解):在第1秒末进入大量请求比如进入4个请求,在第2秒初又进入5个请求,这样就导致1秒末和2秒初这个时间里最高可进入2n个请求

    基于内存的实现:适用于单机,根据场景不同,需要特定设计,需要考虑并发场景,需要加读写锁或者使用Semaphore。

    基于redis的实现:可以单机,可以分布式,但是要考虑redis性能问题,会影响redis性能,看你的场景是否需要redis的高性能。实现思路1:设一个带有信息的key和自增的value,判断并设置过期时间。实现思路2:直接执行制定的lua脚本。

    滑动窗口算法

    通俗来说就是就是计数器算法不需要考虑临界情况最高可进入2n个请求。相比计数器的实现,它的起点不是固定的,而是以开始计数的那个时刻开始为一个窗口。

    案例:1秒5次,我们在200ms内请求了4次,那么我们在200ms-1秒200ms中只能请求1次。

    实现思路:

    • 基于redission的实现
    • 基于sentinel的实现
    • 基于redis的zset的实现
    • 基于Hystrix的实现

    令牌桶算法

    桶里装的是令牌。每次能拿取到令牌,就可以进行访问。并且,令牌会按照速率不断恢复放到令牌桶中直到桶满。

    案例:首先我们要知道,拿到令牌后请求才能通过。比如我们设定速率是一秒5个令牌(也就是1秒五次)。那么我们桶里产出令牌的速率是200ms一个令牌,如果我们在190ms消费了一个令牌,那么下一个请求在400ms才能通过,我300ms时的请求就会被拒绝!

    实现:选用Guava的RateLimiter

    漏桶算法

    可以想象为一个漏桶,你往漏桶注水(发送请求),不管用多大速率注水,水不能超过漏桶容量,超过容量部分请求被拒绝。漏的地方水则以恒定速率流下(请求恒定通过)。

     案例:一个接口只能来请求容量为5,这个时候并发请求来了6个,则最后到达的请求就被拒绝。如果消费速率是1s一个,那么在第一秒时桶里只有四个请求,那么外界再来请求,则会被放在桶里消费。

    实现:这个没接触到,我看他们都是自己写的。欢迎补充

  • 相关阅读:
    快速清除PPT缓存文件或C盘隐藏大文件
    CSS学习笔记
    go-kit grpc调用及中间件封装
    持续精进,改变自己
    聚已内酯偶联小鼠血清白蛋白/小麦麦清白蛋白;PCL-MSA/RSA(试用说明)
    shell正则和元字符
    无聊的一篇博客(如何通过路由器登陆页对固定机器进行网速干扰,如何帮熊孩子戒网瘾)
    SpringCloud alibaba
    npm yarn 和 pnpm 之间命令的区别
    如何通过SQL批量删除重复数据
  • 原文地址:https://blog.csdn.net/wai_58934/article/details/125463910