这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
令牌桶算法和漏桶算法是常见的限流算法,在Sential中,它们分别被用于限流-冷启动模式
和匀速排队模式
。
Sential流控效果:
- 直接拒绝:(RuleConstant.CONTROL_BEHAVIOR_DEFAULT)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException。
- 限流-冷启动:(RuleConstant.CONTROL_BEHAVIOR_WARM_UP)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。
- 匀速排队:(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。 只能对请求进行排队等待
令牌桶算法
令牌桶算法的基本过程如下:
- 令牌桶每秒会有m个令牌入桶。
- 令牌桶的容量为a,当令牌桶已满时,多余的令牌将会被丢弃。
- 当有一个n字节的数据包到达时,消耗n个令牌,然后发送该数据包。
- 当令牌不足消耗时,丢弃或缓存该数据包。
令牌桶算法的核心思想就是通过限定令牌入桶速度,来限制平均处理速度。此外,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的上限,因此它适合于具有突发特性的流量。
令牌桶的实现思路主要有两种:
- 定时任务: 设置每秒的定时任务,实现令牌的每秒入桶。这样的问题在于会极大的消耗系统资源,当令牌桶数量多时,需要非常多的相应的定时任务。
- 延迟计算: 统计令牌消耗的间隔时间(冷却时间),只有当令牌消耗的时候,才会根据冷却时间获得这段时间生成的令牌数。
实际应用可以使用Guava
的RateLimiter
工具类,其采用了延迟计算的实现思路。
漏桶算法
漏桶算法强制控制一个常量的输出速率,而不管输入数据流的突发性。当输入空闲时,该算法不执行任何动作.就像用一个底部开了个洞的漏桶接水一样,水进入到漏桶里,桶里的水通过下面的孔以固定的速率流出,当水流入速度过大会直接溢出,可以看出漏桶算法能强行限制数据的传输速率.如下图所示:
漏桶算法的实现往往依赖于队列,请求到达如果队列未满则直接放入队列,然后有一个处理器按照固定频率从队列头取出请求进行处理。如果请求量大,则会导致队列满,那么新来的请求就会被抛弃。