滑动窗口限流

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

  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. Games101:作业6

    说明 本次作业主要实现对上一次作业代码的重构以及使用BVH加速求交的交点判断和递归调用 代码框架的修改 有影响的改动就是框架中定义了两个结构体一个是光线ray,一个是交点Intersection 交点 ...

  2. Python爬取腾讯视频电影名称和链接(一)

    1 import requests 2 import json 3 from bs4 import BeautifulSoup #网页解析获取数据 4 import sys 5 import re 6 ...

  3. #分块,可撤销并查集#洛谷 5443 [APIO2019]桥梁

    题目 分析 最直接的做法就是在线一边修改边权,询问直接全部重排, 然后用可撤销并查集维护连通块大小,这样时间复杂度为 \(O(qm)\) 同样尽量让大部分的边不需要修改边权,那么每 \(B\) 个操作 ...

  4. OpenHarmony创新赛 | 您有一份创新激励奖待领取 请查收!

      2023开源和信息消费大赛 开放原子开源大赛OpenHarmony创新赛 (以下简称"OpenHarmony创新赛") 正如火如荼的进行当中 赛程也即将进入到提交作品的关键阶段 ...

  5. 轻松上手Jackjson(珍藏版)

    写在前面 虽然现在市面上有很多优秀的json解析库,但 Spring默认采用Jackson解析Json. 本文将通过一系列通俗易懂的代码示例,带你逐步掌握 Jackson 的基础用法.进阶技巧以及在实 ...

  6. openGauss关于PL/SQL匿名块调用测试

    openGauss 关于 PL/SQL 匿名块调用测试 一.原理介绍 PL/SQL(Procedure Language/Structure Query Language)是标准 SQL 语言添加了过 ...

  7. 选择排序的基本实现【数据结构与算法—TypeScript 实现】

    笔记整理自 coderwhy 『TypeScript 高阶数据结构与算法』课程 概念 本质:两两元素相比较,先扫描一遍未排序数列,把未排序的数列中的最小(大)元素,放到数列的已排序的末尾 特性 选择排 ...

  8. 及刻周边惠:拥抱HarmonyOS原子化服务

    原文链接:https://mp.weixin.qq.com/s/Y75eiRlvDLXzoZWzAiZdeg,点击链接查看更多技术内容: 开发背景 及刻周边惠是梦享网络旗下本地生活服务平台,旨在为消费 ...

  9. 一步一步实现 .NET 8 部署到 Docker

    一.前言 本文仅针对操作系统为 CentOS 8 的环境下部署方法进行讲述.如有需要,后续将在其他文章中进行其他系统下的部署方式讲解. 二.准备工作 确保服务器已安装 docker. 可以通过命令 d ...

  10. Vue 路由组件传参的 8 种方式

    我们在开发单页面应用时,有时需要进入某个路由后基于参数从服务器获取数据,那么我们首先要获取路由传递过来的参数,从而完成服务器请求,所以,我们需要了解路由传参的几种方式,以下方式同 vue-router ...