本地限流的常用算法

本文探讨了接口限流的重要性,包括防刷和应对突发流量。介绍了限流方案,如限制并发、令牌桶算法和漏桶算法,并详细讲解了快手团队的Throttling组件,用于本地限制并发数。同时,提到了Guava的RateLimiter实现的平滑突发限流策略,适用于系统预热场景。
摘要由CSDN通过智能技术生成

在大流量app后端模块设计过程中, 接口限流是必须考虑的事情,本文主要聊聊单机限流的一些常用的实现方案, 以及公司实现的一个 本地限制并发数的Throttling简单实现。

限流的存在的必要性

  1. 当下互联网出现突发流量带来的挑战
  2. 防刷

当我们的系统不足以应对当下的流量,那么这个时候我们就需要一种方式阻止流量继续涌入我们的系统,这个时候就需要对用户的请求进行限流

常见限流方案

  1. 限制并发。

利用全局计数器。比如计数器总共允许一百个。我们在进入方法的时候将这个计数器加1,然后执行完方法将这个计数器-1.等到这个计数器变为0或者负数的时候那么就不能在继续进行访问,这个请求就需要拒绝掉。
限制并发是简单粗暴,但是也就是限制的TPS

  1. 令牌桶算法
    使用一个桶来存放请求需要使用的令牌,令牌桶也就是每秒钟里面只有固定数量的令牌个数。如果令牌没有了那么请求被拒绝或者等待。

常见实现 Throttling:
Throttling是快手基础架构团队实现的一个简单的本地限制并发数的组件, 原理是使用DeQueue&CompletableFuture分别实现了同步限流和异步限流的功能,代码相对比较少,实现的也比较优雅。
关键代码如下:


/**
    * 开启 throttling 的perf机制上报,一旦开启,会在perf内埋TL,并在相关组件内读取配置进行相应的打点上报
    */
private static final Kconf<Boolean> ENABLE_THROTTLING_PERF =
        ofBoolean("infra.framework.enableThrottlingPerf", false).build();
private static final Kconf<Duration> CLEAN_UNUSED_THROTTLING_DURATION =
        ofLong("infra.framework.cleanUnusedThrottlingDurationMs", HOURS.toMillis(1))
                .mapper(Duration::ofMillis)
                .build();
private static final ThreadLocal<Deque<Throttling>> CURRENT_THROTTLES = ThreadLocal.withInitial(ArrayDeque::new);
private static final Runnable REGISTER_COUNT_PERF = runOnce(() -> {
   
    ExtendableStatsReporter.register("throttlingPerf.totalCount"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值