常见限流算法介绍(漏桶算法、令牌桶算法)及实现--待整理


1.限流
2.限流算法
  2.1计数器
  2.2 漏桶算法
  2.3 令牌桶算法
  2.4、滑动时间窗
  2.5、三色速率标记法
三、限流实现
  3.1 RateLimiter简介(guava的令牌桶实现)
  3.2 基于 redis 的分布式限流

  3.3 Spring Cloud GateWay整合redis内置RequestRateLimiter限流应用
  3.4 AOP + Semaphore限流应用

http://www.google.com/patents/CN1536815A?cl=zh

guava--RateLimiter源码分析》

RateLimiter和Java中的信号量(java.util.concurrent.Semaphore)类似,Semaphore通常用于限制并发量.

源码注释中的一个例子,比如我们有很多任务需要执行,但是我们不希望每秒超过两个任务执行,那么我们就可以使用RateLimiter:

final RateLimiter rateLimiter = RateLimiter.create(2.0);
void submitTasks(List tasks, Executor executor) {
    for (Runnable task : tasks) {
        rateLimiter.acquire(); // may wait
        executor.execute(task);
    }
}

另外一个例子,假如我们会产生一个数据流,然后我们想以每秒5kb的速度发送出去.我们可以每获取一个令牌(permit)就发送一个byte的数据,这样我们就可以通过一个每秒5000个令牌的RateLimiter来实现:

final RateLimiter rateLimiter = RateLimiter.create(5000.0);
void submitPacket(byte[] packet) {
    rateLimiter.acquire(packet.length);
    networkService.send(packet);
}

另外,我们也可以使用非阻塞的形式达到降级运行的目的,即使用非阻塞的tryAcquire()方法:

if(limiter.tryAcquire()) { //未请求到limiter则立即返回false
    doSomething();
}else{
    doSomethingElse();
}

 

这篇文章,大致原因跟redis集群的重放和备份策略有关,相当于我调用TIME操作,会在主从各执行一次,得到的结果肯定会存在差异,这个差异就给最终逻辑正确性带来了不确定性。在redis 4.0之后引入了redis.replicate_commands()来放开限制。

于是,在 buildLuaScript2 的 lua 脚本最前面加上 “redis.replicate_commands();”,错误得以解决。

AOP+Semaphore实现单节点的接口(方法)限流》

参考: https://github.com/springside/springside4/wiki/Rate-Limiter

https://en.wikipedia.org/wiki/Token_bucket

https://en.wikipedia.org/wiki/Leaky_bucket

https://blog.csdn.net/johnf_nash/article/details/89791808