基于 Redis 实现高并发滑动窗口限流:Java实战与深度解析

Java简单实现高并发redis分布式锁 业务逻辑设计:需要考虑到订单生成、支付、配送、售后等各个环节的业务流程,并尽可能优化业务流程,减少并发冲突。缓存设计:需要考虑到订单状态等数据的缓存,使用Redis等内存数据库缓存热点数据,减少数据库的访问量。安全性设计:需要考虑到订单数据的安全性,使用HTTPS等安全协议保护订单数据的传输过程。数据库设计:需要使用分库分表等技术来解决高并发下数据库的性能问题,避免数据库成为瓶颈。监控设计:需要对系统进行监控,收集性能指标、错误日志等信息,及时发现并解决问题。 阅读详情

在现代分布式系统中,API 限流是保护服务稳定性的关键防线。我曾亲历一个未做限流的支付接口被脚本刷爆,导致整个系统雪崩的惨痛教训。本文将深入探讨如何利用 Redis 实现高性能的滑动窗口限流算法,并提供可落地的 Java 实现方案。

一、为什么需要滑动窗口限流?

固定窗口算法(如每分钟100次)存在临界突变问题:在窗口切换瞬间可能承受双倍流量冲击。滑动窗口通过动态时间区间统计,实现了更平滑精确的流量控制,特别适用于高频敏感场景。

二、核心设计:Redis 有序集合(ZSET)

实现原理:

  1. 使用 ZSET 存储请求时间戳(score=timestamp)

  2. 每个请求到来时:

    • 清除窗口外的旧数据(ZREMRANGEBYSCORE)

    • 统计当前窗口内请求数(ZCARD)

    • 添加新时间戳(ZADD)

  3. 通过 TTL 自动清理过期数据

    import redis.clients.jedis.Jedis;
    import java.time.Instant;
    
    public class SlidingWindowRateLimiter {
        private final Jedis jedis;
        private final String key;
        private final int maxRequests;
        private final long windowMillis;
    
        public SlidingWindowRateLimiter(Jedis jedis, String key, int maxRequests, long windowMillis) {
            this.jedis = jedis;
            this.key = key;
            this.maxRequests = maxRequests;
            this.windowMillis = windowMillis;
        }
    
        public boolean isAllowed() {
            long now = Instant.now().toEpochMilli();
            long windowStart = now - windowMillis;
    
            // 原子操作:移除旧数据并添加新请求
            jedis.zremrangeByScore(key, 0, windowStart);
            jedis.zadd(key, now, String.valueOf(now));
            
            // 设置键过期避免内存泄漏
            jedis.expire(key, windowMillis / 1000 + 1);
    
            // 获取当前窗口请求数
            long count = jedis.zcard(key);
            return count <= maxRequests;
        }
    }

    三、生产环境优化策略

  4. Lua脚本保证原子性
    高并发下需防止竞态条件,使用Redis执行Lua脚本:

    local key = KEYS[1]
    local now = tonumber(ARGV[1])
    local windowStart = tonumber(ARGV[2])
    local maxRequests = tonumber(ARGV[3])
    local expireSec = tonumber(ARGV[4])
    
    redis.call('ZREMRANGEBYSCORE', key, 0, windowStart)
    redis.call('ZADD', key, now, now)
    redis.call('EXPIRE', key, expireSec)
    local count = redis.call('ZCARD', key)
    return count <= maxRequests and 1 or 0

    时间分片优化性能
    当QPS>10k时,可改用时间桶方案:

    // 将1秒窗口分为10个100ms桶
    long bucketSize = 100; 
    long bucket = now / bucketSize * bucketSize;

  5. 集群扩展方案

    • 相同用户路由到固定Redis节点

    • 本地缓存+Redis的二级限流

  6. 时间同步问题
    多服务器时需使用NTP同步时间,否则会出现时间漂移导致限流失效

  7. 热Key解决方案
    对高频key(如秒杀商品)添加随机后缀分片:

  8. 四、基准测试对比

    算法类型QPS上限内存消耗时间精度
    固定窗口12k低低
    滑动窗口(Lua)8k中高
    令牌桶15k高中

    测试环境:Redis 6.2, 4核CPU, 100并发线程

    五、真实场景踩坑记录

通过Redis的ZSET实现滑动窗口限流,不仅解决了固定窗口的临界突变问题,还能在分布式环境中保持高一致性。实际部署时建议结合监控系统(如Prometheus)实时观察限流效果。

  1. 时间同步问题
    多服务器时需使用NTP同步时间,否则会出现时间漂移导致限流失效

  2. 热Key解决方案
    对高频key(如秒杀商品)添加随机后缀分片:

    String shardKey = key + "_" + ThreadLocalRandom.current().nextInt(10);

    突发流量处理
    结合令牌桶算法实现预热机制:

    // 每秒补充10个令牌
    jedis.incrBy(key, 10); 
    jedis.expire(key, 1);

    六、完整生产级实现

    public class RateLimiter {
        private final JedisPool jedisPool;
        private final String luaScript;
        
        public RateLimiter(JedisPool pool) {
            this.jedisPool = pool;
            this.luaScript = "local current = redis.call('zcard', KEYS[1])\n" +
                             "if current >= tonumber(ARGV[1]) then\n" +
                             "    return 0\n" +
                             "end\n" +
                             "redis.call('zadd', KEYS[1], ARGV[2], ARGV[3])\n" +
                             "redis.call('expire', KEYS[1], ARGV[4])\n" +
                             "return 1";
        }
    
        public boolean tryAcquire(String key, int limit, int windowSec) {
            try (Jedis jedis = jedisPool.getResource()) {
                long now = System.currentTimeMillis();
                String member = UUID.randomUUID().toString(); // 唯一标识
                Object result = jedis.eval(luaScript, 1, key, 
                    String.valueOf(limit),
                    String.valueOf(now),
                    member,
                    String.valueOf(windowSec * 2) // 双倍TTL
                );
                return "1".equals(result.toString());
            }
        }
    }

    七、结论与选型建议

    滑动窗口在精确控制场景下表现优异,但需根据业务特点选择:

  3. 电商秒杀:滑动窗口+本地缓存

  4. API网关:令牌桶算法

  5. 金融交易:多层限流(用户/IP/接口)

Redis ZSet+Lua脚本+SpringBoot实战:滑动窗口限流方案从原理到落地 本文介绍了基于Redis ZSet、Lua脚本和SpringBoot的滑动窗口限流方案。相比固定窗口限流,滑动窗口通过划分时间片解决了边界漏洞问题,精度更高。Redis ZSet的有序特性适合存储请求时间戳,Lua脚本确保限流操作的原子性,SpringBoot则提供工程化实现。方案详细拆解了核心逻辑,包括ZSet指令设计、Lua脚本编写以及SpringBoot集成步骤,并提供了完整的可复用代码,兼顾理论深度与实战性,帮助开发者快速落地高精度限流功能。 阅读详情

相关推荐

【Java生产级避坑指南】11. 流量整形实战:自适应限流如何扛住电商大促突发流量?

摘要:某电商平台2023年双11大促期间,商品详情页服务因固定计数器限流遭遇严重故障:QPS从日常800骤升至12000时,系统4秒内大量返回429,6秒后线程池耗尽瘫痪。根源在于固定阈值无法应对突发流量,且未结合系统负载动态调整。本文从实战出发,先解析固定窗口、滑动窗口等5种限流算法的优劣,再深入Guava RateLimiter的令牌桶实现与预热机制,重点落地基于系统负载(CPU、内存、线程数)的自适应限流方案,结合Redis+Lua实现分布式限流。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 981

Java使用Redis滑动窗口实现分布式限流

核心原理:ZSET 时间戳排序 + 窗口清理关键优化:Lua 原子脚本、Spring 集成生产要点:集群分片策略、动态阈值扩展方向结合令牌桶算法实现平滑限流实时监控与自动阈值调整多级限流(用户级、接口级、系统级)通过本教程,你掌握了滑动窗口限流的核心实现与生产级优化技巧。实际项目中需根据业务特点调整时间精度和阈值策略。

因为热爱,所以付出 1452

在VSCode中使用LaTex+(grammarly语法检测,chatgpt翻译,Sumatra PDF 轻量级pdf阅读器)

整个文章分为以下几个内容,打 * 的是必须要安装的。

u011895157的博客 2万+

SpringBoot 项目限流之redis zset滑动窗口

在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。限流可以认为服务降级的一种,限流通过限制请求的流量以达到保护系统的目的。

renhe96421的博客 1468

FlashAttention 快速安装指南(避免长时间编译)

FlashAttention 编译太慢?本篇提供无需编译的预编译 wheel 快速安装方案,适配多版本 Python、PyTorch 和 CUDA,极大节省部署时间!

Junseer的博客 9721

高速SerDes均衡技术解析

均衡技术是高速SerDes链路中补偿信道损耗和失真的核心技术,通过FFE、CTLE和DFE三种主要方法对抗码间干扰(ISI)。FFE在发射端预补偿前光标干扰,CTLE通过提升高频增益补偿信道损耗,DFE则精准消除后光标干扰。三种技术各具优势:FFE实现简单且不放大噪声,CTLE功耗低易于集成,DFE能自适应调整且保持信噪比。这些技术协同工作可有效提升系统传输速率和可靠性。

一只豌豆象的博客 1950

Redis-高并发下缓存失效问题

指查询一个一定不存在的数据,由于缓存是不命中,将去查询数据库,但是 数据库也无此记录,我们没有将这次查询的null写入缓存,这将导致这个不 存在的数据每次请求都要到存储层去查询,失去了缓存的意义。缓存雪崩是指在我们设置缓存时key采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。大量并发只让一个去查,其他人等待,查到以后释放锁,其他 人获取到锁,先查缓存,就会有数据,不用去db。风险: 利用不存在的数据进行攻击,数据库瞬时压力增大,最终导致崩溃。

一位打工仔的博客 626

智能车竞赛走马观碑组:如何高效识别目标板并优化绕行策略(附实战代码)

本文深入探讨了智能车竞赛走马观碑组中,如何构建从图像识别到路径决策的全栈优化方案。针对目标板识别与绕行策略的核心难点,文章详细解析了基于MobileNetV2的高效识别流水线、结合预瞄点与纯追踪算法的平滑路径规划,以及横向与纵向协同控制策略,并提供了实战代码与调试指南,旨在全面提升小车的比赛表现。

o5p6q的博客 884

Redis实现滑动窗口限流

RateLimiter:限流注解RateLimitRule:限流规则RateLimiters:存放多个限流注解的容器,为了可以重复使用该注解// 支持重复注解/*** 限流键前缀* @return*//*** 限流规则* @return*//*** 限流类型* @return*//*** 时间窗口, 单位秒* @return*//*** 允许请求数* @return*/定义一个切面实现限流逻辑:RateLimiterAspect。

weixin_44639291的博客 2004

最全的Hermes安装教程以及Hermes WebUI安装部署和配置指南

* 直接执行命令**

小石头的专栏 1084

linux v3h平台开发系列详解(GMSL摄像头篇):1.11 解串器MIPI 1.5G高速率特殊deskew配置

解串器max96712 deskew配置

xian18809311584的博客 1777

Java实现滑动窗口限流策略:全面解析与代码示例

滑动窗口限流是一种通过细粒度时间划分,实现更平滑的限流效果的算法。它可以有效避免固定窗口在时间边界处流量突增的问题。在滑动窗口中,将一个完整窗口分为多个小区间,计数器会不断刷新,使得统计的请求数更精准。滑动窗口限流是一种灵活而精准的流量控制算法,适合高并发的业务场景。在实际使用中,可以根据业务特点灵活调整窗口大小和分区数量,以平衡流量控制精度与系统开销。希望本文能帮助大家更好地理解和实现滑动窗口限流。

沉淀所学,分享所思,让热爱与成长同行。商务记录AI实战经验,助力开发者快速成长。 热爱AI,希望做出有影响力的技术成果。 技术点亮生活,分享连接价值与机会。 专注AI落地实战,陪你走好技术每一步。 1万+

uniapp - 最新详细实现web-view网页与安卓苹果App端之间互相通信功能,苹果app/安卓app平台与内嵌webview组件内的网页进行相互传值,内置网页与app双向实时通信,详细示例代码

uni-app,Android安卓,苹果ios,app,内嵌webview,第三方H5网页,app和web-view通信传值,web-view引入的页面向App主应用传递数据,App端与webview端相互通信,App端和H5端webview之间的通信,uniapp实现webview和APP之间的传值通信,如何互相传递对象数据,数据传递了接收不到,web-view页面向app内发送消息,监听传递的参数,uni-app和web-view页面相互传参,报错怎么办,跨域,屏幕空白出错,数据交互,解决手机物理返回按

🏆 前端领域优质创作者 4743

Java系统设计与面试深度解析:高并发限流策略之令牌桶与漏桶对比

在高并发系统设计中,限流策略如同交通信号灯般控制着请求的流量节奏。当系统面临突发流量冲击时——无论是电商平台的秒杀活动,还是社交媒体的热点事件——合理的限流机制能有效防止服务雪崩,保障核心业务持续稳定运行。这种技术手段通过预设的规则对超出系统处理能力的请求进行限制或拒绝,成为现代分布式架构中不可或缺的稳定性保障组件。

zuiyuelong的博客 1130

【N32L40X】学习笔记08-定时器的基本定时功能-超时功能

【代码】【N32L40X】学习笔记08-定时器的基本定时功能-超时功能。

Car12 829

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Java面试-如何设计一个秒杀系统?高并发、限流、库存扣减

《Java面试200问》系列:秒杀系统设计全解析 本文深入探讨了高并发秒杀系统的核心设计与实现方案。通过需求分析指出秒杀系统面临的三大挑战:高并发访问、库存超卖问题和限流需求。针对这些难题,文章提出了分布式架构解决方案,包括: 负载均衡分流请求 Redis缓存热点数据 乐观锁/悲观锁防止超卖 令牌桶算法实现限流 系统架构部分详细展示了从单机到分布式集群的演进过程,并提供了MySQL表结构设计示例。最后强调监控和安全机制的重要性,为Java开发者提供了完整的秒杀系统实现思路。

千淘万漉虽辛苦,吹尽狂沙始到金 2万+

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

限流算法深度解析与实用指南

在现代软件开发中,服务的高可用性和稳定性是至关重要的,而限流正是确保这一点的有效技术手段之一。限流可以防止过多的请求在短时间内涌向服务,从而引发服务过载并最终导致崩溃。这一部分,我们将探讨限流的必要性、应用场景以及基本原理,为理解接下来的算法和实现策略打好基础。

逆流的小鱼 2411

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Redis+Lua脚本,分布式限流的终极武器?一线实战全解析!

Redis+Lua脚本实现分布式限流,具有原子性、高性能、简单易用等优势。合理的实现和配置能够有效保护系统,提升用户体验。关注服务端技术精选,获取更多后端实战干货!你在Redis+Lua脚本限流中遇到过哪些坑?欢迎在评论区分享你的故事!

我爱娃哈哈的专栏 1131

网关限流实现方案:从单机到分布式的完整指南

🔥 网关限流实现方案:从单机到分布式 核心要点: 限流必要性:防止突发流量导致系统崩溃,保护后端服务,识别恶意攻击 本地限流:基于Guava实现,高性能但集群环境下不精确 分布式限流:基于Redis+Lua脚本,实现全局精确控制 多维度限流:支持IP、用户ID、API路径等多维度控制 技术选型:本地限流适合单机场景,分布式限流适合集群环境 实现方案对比: 本地限流:内存操作,性能高但集群不均衡 分布式限流:Redis实现,全局精确但有网络开销 最佳实践:根据业务场景选择合适方案,或组合使用两种限流策略。

qq_43414012的博客 697

Spring Boot接口限流实战:从单机到分布式,应对高并发面试与系统保护

在分布式系统与高并发场景下,接口限流是保障服务稳定性的核心技术之一。其核心原理是通过算法控制单位时间内的请求流量,防止突发流量压垮系统,从而保护服务可用性。从技术价值看,限流不仅是系统保护的“保险丝”,更是实现服务降级、熔断等弹性架构的基础。常见的应用场景包括秒杀活动、API开放平台、核心交易链路等,用以平衡系统负载与用户体验。本文聚焦于令牌桶、滑动窗口等主流算法,并结合Spring Boot生态,详细演示如何通过注解驱动快速整合轻量级限流组件,并深入探讨如何利用Redis实现分布式限流,以解决微服务架构下

weixin_34269583的博客 401

Redis实现高并发限流与分布式锁实战指南

在分布式系统中,流量控制和并发控制是保障稳定性的核心技术。Redis凭借其单线程原子特性和高性能,成为实现限流算法(如令牌桶、漏桶)和分布式锁的理想选择。令牌桶算法通过动态发放令牌控制流量,适合秒杀等突发场景;漏桶算法则强制恒定速率,保护下游系统。分布式锁通过Redis的原子操作和续期机制解决并发冲突,需注意锁过期、重入等陷阱。这些技术广泛应用于电商大促、API管理等高并发场景,能有效防止系统雪崩。本文结合双十一等实战案例,详解如何用Redis+Lua实现工业级解决方案。

weixin_32576389的博客 166

高并发限流实战指南:四种限流算法解析与 Spring Cloud Gateway、Sentinel 落地实践(advanced-java)

限流是保障高并发系统稳定运行的关键手段之一,它通过限制系统的输入与输出流量,在系统吞吐量达到测算阈值时主动拒绝、延迟或部分拒绝请求,从而保护后端服务不被瞬时流量打垮。本文基于 advanced-java 项目中 [如何限流?在工作中是怎么做的?](https://link.gitcode.com/i/56888c134e5ddd04adaad6e5364d0959) 一文,系统讲解计数器、滑动窗口

gitblog_00560的博客 463

Redisson滑动窗口限流实战:从原理到微服务熔断应用

本文深入解析了滑动窗口限流原理及其在微服务架构中的重要性,并详细演示了如何利用Redisson分布式限流器(RRateLimiter)在Spring Boot项目中实现精准流量控制。文章重点探讨了将滑动窗口限流与微服务熔断降级策略深度结合的实战方案,通过Feign客户端集成,构建能抵御流量洪峰的稳健系统,并分享了参数调优与常见避坑指南。

jenkins8butler的博客 502

Redis核心特性与高并发场景实战解析

内存数据库通过将数据存储在内存中实现高速读写,其中Redis作为典型代表支持丰富的数据结构如字符串、哈希和有序集合,其单线程模型保证了操作的原子性。在分布式系统中,Redis常用于实现缓存、分布式锁和限流等高并发场景,通过RDB/AOF持久化机制确保数据可靠性。针对缓存击穿问题可采用互斥锁方案,而滑动窗口算法能精准实现API限流。作为数据结构服务器,Redis在实时排行榜、社交关系计算等场景展现独特优势,配合发布订阅功能还可构建轻量级消息队列。合理使用Pipeline和Key分片能有效提升吞吐量,但需注意内

weixin_30552811的博客 405

LLM应用限流实战:令牌桶、滑动窗口与配额管理

在分布式系统和高并发场景下,限流是保障服务稳定的核心手段,其本质是通过控制请求速率和资源消耗,防止系统过载。令牌桶算法以固定速率补充令牌并允许突发流量,滑动窗口则通过精细化时间切片消除临界突刺问题,二者各有适用场景。对于LLM应用而言,限流不仅是保护后端,更直接关联成本控制、上游供应商API配额以及多租户公平性。在大模型API网关中,结合Redis与Lua脚本实现原子化的令牌桶和滑动窗口,并设计多层配额记账体系,可以同时管理秒级速率与中长期Token总量。文章从限流基础原理出发,深入工程实践,演示如何通过网

weixin_34008933的博客 429

Java大厂面试实战:电商高并发场景下的Spring Boot+Redis+Kafka技术栈深度解析

缓存设计:多级缓存、雪崩/穿透/击穿解决方案消息队列:Kafka选型、可靠性保证、幂等性处理高可用:限流、熔断、降级、监控告警性能调优:JVM参数、GC优化、内存泄漏排查架构设计:秒杀系统、最终一致性、分布式锁希望这篇文章能帮助正在准备面试的同学们,祝大家都能拿到心仪的Offer!本文内容仅供参考,实际面试中请结合自己的项目经验作答。

qq_64603835的博客 208
上一篇: 面试官问“了解 MySQL 索引失效的场景吗?请说说” —— 深入剖析与避坑指南
下一篇: 限流算法深度探索:从理论到实践的生产级避坑指南
码里看花‌
博客等级 码龄8年 321粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码里看花‌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值