滑动窗口限流

滑动窗口限流是一种常用的限流算法,通过维护一个固定大小的窗口,在单位时间内允许通过的请求次数不超过设定的阈值。具体来说,滑动窗口限流算法通常包括以下几个步骤:

  1. 初始化:设置窗口大小、请求次数阈值和时间间隔。
  2. 维护窗口:将请求按照时间顺序放入窗口中,并保持窗口内请求数量不超过阈值。
  3. 检查通过:每当有新的请求到达时,检查窗口内请求的总数是否超过阈值,如果未超过则允许通过,同时移除窗口最老的请求。
  4. 更新窗口:随着时间的推移,更新窗口内的请求情况,确保窗口内的请求符合限流条件。

滑动窗口限流算法可以有效控制系统的请求流量,避免系统被大量请求压垮。同时,由于其简单高效的特点,被广泛应用于接口限流、流量控制等场景中。需要注意的是,滑动窗口限流算法对于突发请求并不能完全解决问题,因此在实际应用中可能需要结合其他策略进行综合考虑。

基于redis-zset实现的滑动窗口算法流程

核心代码

/**
* 滑动窗口限流. 需要注意的是,我们要定期清楚过期的key,否则会导致内存泄漏,可以使用ZREMRANGEBYSCORE方法实现.
* @param key 限流的key
* @param timeWindow 单位时间,秒
* @param limit 窗口大小,单位时间最大容许的令牌数
* @param runnable 成功后的回调方法
*/
public void slidingWindow(String key, int timeWindow, int limit, Runnable runnable) {
Long currentTime = System.currentTimeMillis();
if (redisTemplate.hasKey(key)) {
Long intervalTime = timeWindow * 1000L;
Long from = currentTime - intervalTime;
Integer count = redisTemplate.opsForZSet().rangeByScore(key, from, currentTime).size();
if (count != null && count >= limit) {
throw new RedisLimitException("每" + timeWindow + "秒最多只能访问" + limit + "次.");
}
log.info("from key:{}~{},current count:{}", from, currentTime, count);
}
redisTemplate.opsForZSet().add(key, UUID.randomUUID().toString(), currentTime);
Optional.ofNullable(runnable).ifPresent(o -> o.run());
}

上面实现了一个基于时间戳为主要窗口依据的滑动窗口限流逻辑,由于zset的数据量会随着时间的流失而变大,所以我们需要定期再根据score来清理它。

/**
* 清期昨天的zset元素,这块应该写个任务调度,每天执行一次,清量需要的zset元素.
* @param key
*/
public void delByYesterday(String key) {
Instant currentInstant = Instant.now();
Instant oneDayAgoInstant = currentInstant.minusSeconds(86400);
long oneDayAgoTimeMillis = oneDayAgoInstant.toEpochMilli();
redisTemplate.opsForZSet().removeRangeByScore(key, 0, oneDayAgoTimeMillis); }

上面代码逻辑,事实上,我们可以通过其它语言去实现,比较通过go可以实现相关的逻辑,从新可以在MSE网关上实现限流功能。

算法~利用zset实现滑动窗口限流的更多相关文章

  1. ASP.NET Core中使用滑动窗口限流

    滑动窗口算法用于应对请求在时间周期中分布不均匀的情况,能够更精确的应对流量变化,比较著名的应用场景就是TCP协议的流量控制,不过今天要说的是服务限流场景中的应用. 算法原理 这里假设业务需要每秒钟限流 ...

  2. Redis的自增也能实现滑动窗口限流?

    限流是大家开发之路上一定会遇到的需求.比如:限制一定时间内,接口请求请求频率:一定时间内用户发言.评论次数等等,类似于滑动窗口算法.这里分享一份拿来即用的代码,一起看看如何利用常见的 Redis 实现 ...

  3. ASP.NET Core中使用固定窗口限流

    算法原理 固定窗口算法又称计数器算法,是一种简单的限流算法.在单位时间内设定一个阈值和一个计数值,每收到一个请求则计数值加一,如果计数值超过阈值则触发限流,如果达不到则请求正常处理,进入下一个单位时间 ...

  4. 算法与数据结构基础 - 滑动窗口(Sliding Window)

    滑动窗口基础 滑动窗口常用来解决求字符串子串问题,借助map和计数器,其能在O(n)时间复杂度求子串问题.滑动窗口和双指针(Two pointers)有些类似,可以理解为往同一个方向走的双指针.常用滑 ...

  5. SpringCloud(六)之 网关概念、Zuul项目搭建-(利用Zuul 实现鉴权和限流实战)

    一.网关概念 1.什么是路由网关 网关是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求.鉴权.监控.缓存.限流等功能.它将"1对N"问题转换成 ...

  6. Sentinel源码解析三(滑动窗口流量统计)

    前言 Sentinel的核心功能之一是流量统计,例如我们常用的指标QPS,当前线程数等.上一篇文章中我们已经大致提到了提供数据统计功能的Slot(StatisticSlot),StatisticSlo ...

  7. .NET服务治理之限流中间件-FireflySoft.RateLimit

    概述 FireflySoft.RateLimit自2021年1月发布第一个版本以来,经历了多次升级迭代,目前已经十分稳定,被很多开发者应用到了生产系统中,最新发布的版本是3.0.0. Github:h ...

  8. 基于令牌桶算法实现的SpringBoot分布式无锁限流插件

    本文档不会是最新的,最新的请看Github! 1.简介 基于令牌桶算法和漏桶算法实现的纳秒级分布式无锁限流插件,完美嵌入SpringBoot.SpringCloud应用,支持接口限流.方法限流.系统限 ...

  9. tcp协议头窗口,滑动窗口,流控制,拥塞控制关系

    参考文章 TCP 的那些事儿(下) http://coolshell.cn/articles/11609.html tcp/ip详解--拥塞控制 & 慢启动 快恢复 拥塞避免 http://b ...

  10. 【Distributed】限流技巧

    一.概述 1.1 高并发服务限流特技 1.2 为什么要互联网项目要限流 1.3 高并发限流解决方案 二.限流算法 2.1 计数器 2.2 滑动窗口计数 2.3 令牌桶算法 使用RateLimiter实 ...

随机推荐

  1. 【FastDFS】面试官:如何实现文件的大规模分布式存储?(全程实战)

    写在前面 在<[FastDFS]小伙伴们说在CentOS 8服务器上搭建FastDFS环境总报错?>一文中,详细的介绍了如何在CentOS 8服务器行搭建FastDFS环境.在生产环境中, ...

  2. Spring Cloud Alibaba服务的注册与发现之Nacos部署

    1.Nacos官网介绍 Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管理.Nacos 帮助您更敏捷和容 ...

  3. DenseBox:思想超前的早期Anchor-free研究 | CVPR 2015

    DenseBox检测算法的设计十分超前,如今很多Anchor-free方法有其影子,如果当时不是比Faster R-CNN晚了一点出现,可能目标检测领域很早就开始往Anchor-free的方向发展了 ...

  4. KingbaseES 使用百分比函数获取中位数

    客户从Oracle数据库迁移至KingbaseES数据库,应用中使用MEDIAN函数来求中位数.KingbaseES数据库中没有MEDIAN函数,但可以通过百分比函数来实现相应的功能. MEDIAN ...

  5. Windows下获取设备管理器列表信息-setupAPI

    背景及问题: 在与硬件打交道时,经常需要知道当前设备连接的硬件信息,以便连接正确的硬件,比如串口通讯查询连接的硬件及端口,一般手工的方式就是去设备管理器查看相应的信息,应用程序如何读取这一部分信息呢, ...

  6. 使用sbt对Scala程序进行打包并运行(Spark单机运行)

    十.使用sbt对Scala程序进行打包并运行(Spark单机运行) 在./sparkapp 中新建文件 simple.sbt(vim ./sparkapp/simple.sbt),添加内容如下,声明该 ...

  7. python 国家标准行业编码标准格式化处理

    代码在上次的基础上做了一点优化,之前对项目要的最终结果理解有些偏差: 原始数据的那一列行业编码是存在三位数和四位数的,我上次理解的三位数就是分割成两位数进行查找,其实三位数的编码是由于第一位的0没有显 ...

  8. C语言线程安全问题

    线程安全问题 #include <stdio.h> #include <tinycthread.h> #include <io_utils.h> int count ...

  9. C++ 开发者必读经典书籍推荐

    如果你正在学习C++,那么一本好的教材或参考书可以事半功倍.以下是几本我个人推荐的C++书籍或视频 C++基础 看书 C++ Primer C++程序设计语言 Effective C++ More E ...

  10. jemter返回结果中文乱码

    如图,返回的结果,中文出现乱码 对于这个问题有两种解决方法 第一种:修改jemeter文件,需要重启jemter 在 bin 目录下,找到  jmeter.properties  这个文件,修改编码格 ...