在这里插入图片描述

博主 默语带您 Go to New World.
个人主页—— 默语 的博客👦🏻 优秀内容
《java 面试题大全》
《java 专栏》
《idea技术专区》
《spring boot 技术专区》
《MyBatis从入门到精通》
《23种设计模式》
《经典算法学习》
《spring 学习》
《MYSQL从入门到精通》数据库是开发者必会基础之一~
🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭
🪁 吾期望此文有资助于尔,即使粗浅难及深广,亦备添少许微薄之助。苟未尽善尽美,敬请批评指正,以资改进。!💻⌨


默语是谁?

大家好,我是 默语,别名默语博主,擅长的技术领域包括Java、运维和人工智能。我的技术背景扎实,涵盖了从后端开发到前端框架的各个方面,特别是在Java 性能优化、多线程编程、算法优化等领域有深厚造诣。

目前,我活跃在CSDN、掘金、阿里云和 51CTO等平台,全网拥有超过10万的粉丝,总阅读量超过1400 万。统一 IP 名称为 默语 或者 默语博主。我是 CSDN 博客专家、阿里云专家博主和掘金博客专家,曾获博客专家、优秀社区主理人等多项荣誉,并在 2023 年度博客之星评选中名列前 50。我还是 Java 高级工程师、自媒体博主,北京城市开发者社区的主理人,拥有丰富的项目开发经验和产品设计能力。希望通过我的分享,帮助大家更好地了解和使用各类技术产品,在不断的学习过程中,可以帮助到更多的人,结交更多的朋友.


我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。


流量控制算法:固定窗口限流策略详解 🚀

摘要
在如今的高并发系统中,流量控制是保障服务稳定运行的关键手段之一。限流技术可以防止系统因过载而崩溃,其中“固定窗口”限流策略因其简单高效的特点在很多场景中被广泛使用。本文将详细介绍固定窗口限流的设计思路、实现方法,并解析其优缺点,帮助开发者更好地掌握限流技术的应用。


引言

随着互联网应用规模的扩大,流量波动性日益增加,合理的流量控制方案成为开发者的必修课。限流策略众多,而固定窗口限流是一种经典的限流方式,适合于初学者快速上手。在本文中,我们将通过详尽的设计思路、代码示例和具体场景来帮助小白开发者理解固定窗口的限流原理和实现方式。


正文

什么是固定窗口限流?🕰️

固定窗口限流是一种简单的限流策略,通过将时间划分为固定长度的窗口,限制每个时间窗口内的请求次数。当窗口内请求数达到指定阈值,剩余请求将被直接丢弃,等待进入下一时间窗口时重置。


固定窗口限流的设计思路 🔍

核心设计要点
  1. 时间窗口划分:将时间划分为固定长度的窗口(例如1秒)。
  2. 计数限制:在窗口内对请求计数,达到阈值后丢弃窗口内的剩余请求。
  3. 计数重置:时间窗口结束后,重置计数,允许新的请求进入。
举例说明

假设我们对接口A每秒钟允许的最大请求数是100,时间窗口设为1秒。每秒只允许100个请求进入,超过这个数量的请求将被丢弃,等待下一个时间窗口再重新计数。


固定窗口限流的缺点分析 ⚠️

尽管固定窗口限流在大部分场景下效果显著,但也存在一些局限性:

  • 流量峰值偏高:在相邻两个时间窗口的边界处,流量峰值可能达到阈值的两倍。这是因为前一个窗口的最后时刻和下一个窗口的起始时刻可以各自达到阈值,从而引发瞬间的流量冲击。
  • 灵活性较低:无法适应流量随时间波动的情况,适合于流量稳定、无突发请求的场景。

固定窗口限流的代码实现 💻

以下是一个用Java实现的简单固定窗口限流代码示例。此实现仅为基本示例,在实际生产环境中可能需要更复杂的限流逻辑。

import java.util.concurrent.atomic.AtomicInteger;

public class FixedWindowRateLimiter {
    private final int limit; // 每窗口最大请求数
    private final long windowSize; // 窗口大小,单位:毫秒
    private long windowStart; // 当前窗口开始时间
    private AtomicInteger count; // 当前窗口请求计数

    public FixedWindowRateLimiter(int limit, long windowSizeInMillis) {
        this.limit = limit;
        this.windowSize = windowSizeInMillis;
        this.windowStart = System.currentTimeMillis();
        this.count = new AtomicInteger(0);
    }

    public boolean allowRequest() {
        long currentTime = System.currentTimeMillis();

        synchronized (this) {
            if (currentTime - windowStart >= windowSize) {
                // 新窗口开始
                windowStart = currentTime;
                count.set(0);
            }

            if (count.incrementAndGet() <= limit) {
                return true; // 请求通过
            } else {
                return false; // 请求被拒绝
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        FixedWindowRateLimiter limiter = new FixedWindowRateLimiter(5, 1000);

        for (int i = 0; i < 10; i++) {
            System.out.println("请求" + (i + 1) + ": " + (limiter.allowRequest() ? "通过" : "拒绝"));
            Thread.sleep(100);
        }
    }
}

代码解释

  1. 构造方法:初始化请求限制次数和窗口大小。
  2. allowRequest()方法:通过当前时间判断窗口是否过期,如果是则重置计数,否则增加请求计数。
  3. main方法测试:模拟发送10个请求,每秒允许5个请求通过,超出的将被拒绝。

优化和注意事项

在高并发环境下,可以将窗口计数逻辑转移到Redis等分布式缓存系统中,提升分布式环境的限流效果。


总结

固定窗口限流是一种实现简单、适用广泛的限流方案。它适合于简单的流量限制需求,但对于流量波动较大的系统,需要结合其他限流算法(如滑动窗口或令牌桶)进行优化。


参考资料


如果你对流量控制有更深入的兴趣,欢迎加我微信,我们一起交流吧!😊

在这里插入图片描述


🪁🍁 希望本文能够给您带来一定的帮助🌸文章粗浅,敬请批评指正!🍁🐥

如对本文内容有任何疑问、建议或意见,请联系作者,作者将尽力回复并改进📓;(联系微信:Solitudemind )

点击下方名片,加入IT技术核心学习团队。一起探索科技的未来,共同成长。

在这里插入图片描述

更多推荐