限流算法之计数器算法

本文介绍了计数器法作为限流算法的一种简单实现方式,适用于限制接口在一分钟内的访问次数不超过100次。在每次请求时,计数器加一并检查是否超出限制。当时间窗口超出设定间隔时,计数器重置。该方法适用于分布式环境,但存在临界问题,可能无法平滑处理流量突增。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

计数器法是限流算法里最简单也是最容易实现的一种算法。

假设一个接口限制一分钟内的访问次数不能超过100个,维护一个计数器,每次有新的请求过来,计数器加一,这时候判断,如果计数器的值小于限流值,并且与上一次请求的时间间隔还在一分钟内,

允许请求通过,否则拒绝请求,如果超出了时间间隔,要将计数器清零。

/**
 * 限流算法集合
 */
@Slf4j
public class RateLimitUtils {

    //初始时间
    private static long startTime = System.currentTimeMillis();
    //初始计数值
    private static final AtomicInteger ZERO = new AtomicInteger(0);
    //时间窗口限制
    private static final long interval = 1000;
    //限制通过请求
    private static int limit = 100;
    //请求计数
    private AtomicInteger requestCount = ZERO;

    /**
     * 固定时间窗口算法
     * <p>
     *     可以使用在分布式环境下,使用单点存储计数值,比如redis、并且设置自动过期时间,这时候就可以统计整个集群的流量,并且进行限流。
     *     缺点是不能处理临界问题,或者说限流策略不够平滑;
     *     可能在限流临界点来了双倍的流量,c超过系统的限制;
     *     计数器限流允许出现 2permitsPerSecond 的突发流量,可以使用*滑动窗口算法去优化。
     * </p>
     * @return
     */
    public boolean tryAcquire() {
        long now = System.currentTimeMillis();
        //在时间窗口内
        if (now < startTime + interval) {
            //判断是否超过最大请求
            if (requestCount.get() < limit) {
                requestCount.incrementAndGet();
                return true;
            }
            log.info("当前时间窗口内已经超过最大请求数");
            return false;
        } else {
            //新一轮时间窗口开启,超时重置
            startTime = now;
            requestCount = ZERO;
            return true;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值