限流器设计思路(浅入门)
限流器(Rate Limiter)是一种用于控制系统资源利用率和质量的重要机制。它通过限制单位时间内可以执行的操作数量,从而防止系统过载和保护服务的可靠性。在程序设计中,可以使用多种方式来实现限流器,下面是几个常见方案的介绍:
令牌桶算法
漏桶算法
划窗算法
固定窗口算法(缺点很大!)
基于计数器的流量控制算法
...
令牌桶算法(Token Bucket)
令牌桶算法是一种常见的限流实现方式。它维护一个存放令牌的桶,以固定的速率向桶中添加令牌。每次请求到来时,需要从桶中获取一个令牌,只有当桶中有足够的令牌时,请求才能被处理。否则,请求将被拒绝或阻塞。
![](https://static001.geekbang.org/infoq/bd/bdad1d79b189752a83dd7920b6aa78c6.png)
实现思路如下:
维护一个固定大小的令牌桶和一个记录上一次令牌被添加到桶中的时间戳。
以固定的速率(每秒生成的令牌数)向桶中添加令牌。
当请求到来时,尝试从桶中获取一个令牌。如果桶中有令牌,则处理请求并消耗一个令牌;否则,拒绝或阻塞请求。
使用锁或其他同步机制来保证线程安全。
code:
漏桶算法(Leaky Bucket)
漏桶算法类似于令牌桶算法,不同之处在于它维护一个存放请求的队列,而不是令牌桶。当请求到来时,它们会被添加到队列中。队列以固定的速率漏水,即以固定的速率处理请求。
![](https://static001.geekbang.org/infoq/b5/b54d70244ea35e3a519f2e567a72fe56.png)
实现思路如下:
维护一个固定大小的请求队列和一个上次处理请求的时间戳。
当请求到来时,将其添加到队列中。如果队列已满,则拒绝或阻塞请求。
以固定的速率(每秒处理的请求数)从队列中取出请求并处理。
使用锁或其他同步机制来保证线程安全。
code:
滑动窗口(Sliding Window)
滑动窗口算法通过维护一个固定大小的窗口来限制单位时间内的请求数。当请求到来时,它会检查窗口内的请求数是否已达到限制。如果没有,则允许请求;否则,拒绝或阻塞请求。窗口会随着时间推移而滑动,移除较早的请求记录。
冷知识:TCP 协议中数据包的传输,同样也是采用滑动窗口来进行流量控制。
实现思路如下:
维护一个队列或其他数据结构来存储请求的时间戳。
当请求到来时,将其时间戳添加到队列中。
检查队列中最近的一段时间内(窗口大小)的请求数是否超过限制。如果没有,则允许请求;否则,拒绝或阻塞请求。
定期(或在每次请求到来时)移除队列中较早的请求记录,以维护窗口大小。
使用锁或其他同步机制来保证线程安全。
Reference:https://blog.csdn.net/legend050709/article/details/114917637
原理:需要先看看固定窗口算法的原理和缺点,
![](https://static001.geekbang.org/infoq/55/55c68efd10533c9521f82d5bfbe0a6f0.png)
动图:
![](https://static001.geekbang.org/infoq/d5/d51d64f71379272a60b2663a78bbd102.png)
![](https://static001.geekbang.org/infoq/be/be7badc13746783a69378c872935ded8.png)
![](https://static001.geekbang.org/infoq/48/48352046efbd45e57ecf82e921daa696.gif)
code:
演示 code:
out:
总结
这三种算法都是通过控制请求的速率或数量来实现限流,但具体的实现方式有所不同。令牌桶算法和漏桶算法都依赖于时间来控制速率,而滑动窗口算法则是基于请求数量来控制。它们各有优缺点,适合不同的场景。具体选择哪种需要自己根据应用场景进行选择和调整。
同时,也可以考虑使用现有的限流器库或框架,如 Guava RateLimiter、Netflix Hystrix 等,以简化开发过程。
文章转载自:Mysticbinary
评论