一 算法

滑动窗口算法弥补了计数器算法的不足。滑动窗口算法把间隔时间划分成更小的粒度,当更小粒度的时间间隔过去后,把过去的间隔请求数减掉,再补充一个空的时间间隔。

如下图所示,把1分钟划分为10个更小的时间间隔,每6s为一个间隔。

1 一个时间窗口为1分钟,滑动窗口分成10个格子,每个格子6秒。

2 每过6秒,滑动窗口向右移动1个格子。

3 每个格子都有独立的计数器。

4 如果时间窗口内所有的计数器之和超过了限流阀值,则触发限流操作。

如下图所示,滑动窗口算法比计数器算法控制得更精细。

用户在0:59 时刻发送了100个请求,第10个格子的计数器增加100,下一秒的时候时间窗口向右移动1格,这时再来100个请求就超过了阈值,不会处理这100个请求,这样就避免了计数器场景出现的问题。

滑动窗口设置得越精细,限流的效果越好,但滑动窗口的时间间隔(小格子)多了,存储的空间也会增加。

二 需求

1 设计一个滑动窗口,窗口有10个格子,每个格子10秒,每隔10秒移动一格。

2 装满所有格子的时间为 10 * 10 = 100 秒。也就是说时间窗口是 100 秒。

3 从100秒开始,开始滑动,新请求数开始覆盖老请求数。

三 代码

package currentLimit;import java.util.Date;
import java.util.Random;/**
* @className: CounterLimit
* @description: 滑动窗口算法
* @date: 2022/1/8
* @author: cakin
*/
public class SlideWindowLimit {// 滑动窗口大小static final int size = 10;// 滑动窗口数组,每移动一个格子,更新对应数据项的值static int window[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};// 理解为移动窗口中正在计数的格子static int curId = 0;// 记录上次统计时间static Date lastDate = new Date();// 当前窗口计数总和static int counter = 0;/*** 功能描述:模拟一次请求是否限流** @return true:限流 false;不限流* @author 贝医* @date 2022/1/8* @description:*/static boolean slideWindowLimit() {// 获取当前时间Date now = new Date();// 当前时间同上次记录时间的间隔,单位为秒long time = (now.getTime() - lastDate.getTime()) / 1000;// 按照新的移动窗口进行计数if (time >= 10) {// 当前计数格子的下一个格子将被清掉重写curId++;curId = curId % size;int newCurId = curId;// 下一个格子将被清掉,总数据减掉counter = counter - window[newCurId];// 新格子设置为1window[newCurId] = 1;// 记录滑动的时间lastDate = now;} else {// 当前计数的格子++window[curId];}++counter;return counter >= 1000;}// 测试方法public static void main(String[] args) {for (; ; ) {// 模拟一秒try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}Random random = new Random();int i = random.nextInt(3);// 模拟1秒内请求8次if (i == 1) {for (int j = 0; j < 8; j++) {if (slideWindowLimit()) {System.out.println("限流了" + counter);} else {System.out.println("没限流" + counter);}}} else if (i == 2) { // 模拟1秒内请求9次for (int j = 0; j < 9; j++) {if (slideWindowLimit()) {System.out.println("限流了" + counter);} else {System.out.println("没限流" + counter);}}} else { // 模拟1秒内请求10次for (int j = 0; j < 10; j++) {if (slideWindowLimit()) {System.out.println("限流了" + counter);} else {System.out.println("没限流" + counter);}}}}}
}

四 测试

五 说明

记录滑动窗口中的请求数。滑动窗口中的请求数控制在 1000以内。滑动窗口能记录100秒的请求,所以如果每秒请求不超过10,不会限流。测试用例也是这样设计的,每秒模拟发送的请求为8次,9次,10次。从测试结果来看,符合预期。

限流之滑动窗口算法实战相关推荐

  1. Sentinel限流及其滑动窗口算法

    Sentinel限流及其滑动窗口算法 Sentinel的限流原理 滑动时间窗口算法 Sentinel的限流原理 限流效果,对应有DefaultController快速失败 WarmUpControll ...

  2. 什么是限流?为什么会限流呢?常见的限流算法【固定窗口限流、滑动窗口限流、漏桶限流、令牌桶限流】是什么呢?

    什么是限流?为什么会限流呢?常见的限流算法[固定窗口限流.滑动窗口限流.漏桶限流.令牌桶限流]是什么呢? 什么是限流? 为什么会限流? 1. 固定窗口限流算法 1.1 什么是固定窗口限流算法 1.2 ...

  3. 限流的基本原理及算法实现

    一.限流的基本原理 它的目的是确保系统高效.稳定地运行,确保请求能够快速处理的同时,保障系统不被流量压垮. 限流通常是利用某种算法实现限流器,来达到限制流量的目的.通常,限流器中会有一个定时器,它主要 ...

  4. 微服务限流及熔断一:四种限流算法(计数器算法、滑动窗口算法、令牌限流算法、漏桶限流算法)

    引言 本篇内容根据<spring cloud alibaba 微服务原理与实战>中内容摘取,希望和大家分享限流的思想,本篇不涉及代码层面的实现. 限流的目的 目的:通过限制并发访问数或者限 ...

  5. 【面试大全-高并发】-限流策略有哪些,滑动窗口算法和令牌桶区别,使用场景

    参考思路:限流算法常用的几种实现方式有如下四种:计数器.滑动窗口.漏桶和令牌桶: ● 计数器: ○ 思想:在固定时间窗口内对请求进行计数,与阀值进行比较判断是否需要限流,一旦到了时间临界点,将计数器清 ...

  6. sentinel 时间窗口_Sentinel滑动窗口算法

    在前面搞清楚了Sentinel的使用后,大致理了一下Sentinel的责任链,搞清楚了这个,基本就已经梳理清楚sentinel-core模块的大部分内容,顺着这条链路可以继续梳理很多东西. 知其然.知 ...

  7. 滑动窗口算法精讲(Sliding Window Algorithm)

    文章目录 滑动窗口算法精讲(Sliding Window Algorithm) 简介 步骤及算法模板 模板1 模板2 leetcode例题讲解 入门级 209. 长度最小的子数组 思路: 代码实现 2 ...

  8. 列表左右箭头滑动_我写了一套框架,把滑动窗口算法变成了默写题

    读完本文,你可以去力扣拿下如下题目: 76.最小覆盖子串 567.字符串的排列 438.找到字符串中所有字母异位词 3.无重复字符的最长子串 ----------- 鉴于前文 二分搜索框架详解 的那首 ...

  9. 滑动窗口算法_有点难度,几道和「滑动窗口」有关的算法面试题

    前言科普:什么是滑动窗口算法 滑动问题包含一个滑动窗口,它是一个运行在一个大数组上的子列表,该数组是一个底层元素集合. 假设有数组 [a b c d e f g h ],一个大小为 3 的 **滑动窗 ...

最新文章

  1. 微软资深算法工程师为AI初学者量身打造的机器学习入门书上市啦!
  2. Dubbo——Dubbo协议整合Jackson序列化解决方案
  3. appengine_在Google的AppEngine上升级到Java 7
  4. 【OS学习笔记】三十五 保护模式十:中断描述符表、中断门和陷阱门
  5. 如何解决远程windows服务器安装matlab出现License Manager Error-103问题
  6. Codeforces Global Round 14, C. Phoenix and Towers
  7. CentOS 6.7 x64 使用pptpd搭建***服务器
  8. DRF的@action装饰器
  9. 提升测试效率都有哪些具体手段?
  10. 小程序源码:经典语录大全微信小程序源码下载多种分类语录-多玩法安装简单
  11. 废物利用!电路板元器件焊拆必备姿势、焊接技巧、维修拆焊方法
  12. 顺丰快递:请签收Netty灵魂十连问
  13. 调用本地主干的预训练的.pth文件
  14. SpringBoot使用druid的密码加密
  15. layui自定义验证表单
  16. python最佳编程语言_前十大编程语言你会几种?
  17. 使用case when,union all实现sql行转列、列转行
  18. 企业级飞速低代码 | 这是一篇关于低代码平台的非完整推荐
  19. lucene6中配置IK Analyzer同义词分词器
  20. 7-1 jmu-JavaPython-统计文字中的单词数量并按出现次数排序 (25 分)

热门文章

  1. MVC框架的Model数据验证
  2. Android FILE_PROVIDER_PATHS 冲突错误 meta-data#android.support.FILE_PROVIDER_PATHS@resource
  3. Inkscape教程:形状工具
  4. GLFore动平衡仪N600的正确使用方法
  5. 数据分析工具实例:通过数据展示对转基因食品的思考
  6. 十多个配色网站助你获取更高级的配色
  7. MySQL delete 语句
  8. HTML table合并行列后,使用百分比设置列宽
  9. oracle分页怎么查询,Oracle如何实现分页查询 Oracle分页查询代码实例
  10. php网站pc域名和手机域名,手機移動端網站和電腦PC端網站域名使用與跳轉PHP代碼...