首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

6种限流方法之服务端时间窗口算法

时间窗口算法

又名滑动时间算法,所谓的滑动时间算法指的是以当前时间为截止时间,往前取一定的时间,比如取60s的时间,在这60s时间内最大的访问数为100。此时算法的执行逻辑为,先清除这60s 之前的所有请求记录,再计算当前集合内请求数是否大于设定的最大请求数100,如果大于100则执行限流拒绝策略,否则插入本次请求记录并返回可以正常执行的标识给客户端。

滑动时间窗口如下图所示:

其中每一个小格子代表10s,被红色虚线包围的时间段则为需要判断的时间间隔,比如60s允许100次请求,那么红色虚线部分则为60s。

如何实现?

借助Redis的有序集合ZSet来实现时间窗口算法限流,实现的过程是:

第一步:先使用ZSet的key存储限流的ID,score用来存储请求的时间。

第二步:每次有请求访问来了之后,先清空之前时间窗口的访问量,统计目前时间窗口的个数与最大允许访问量对比。

第三步:如果大于等于最大访问量则返回 false 执行限流操策略,负责允许执行业务逻辑,并且在 ZSet 中添加一条有效的访问记录。

代码实操

我们借助 Jedis 包来操作 Redis,首先在pom.xml中添加Jedis的jar包:

redis.clients jedis 3.3.0

具体的 Java代码如下:

package com.example.demo;

import redis.clients.jedis.Jedis;

/** * 6种限流方法之服务端时间窗口算法 * * @author www.jiagou1216.com */public class RedisLimit { /** * Redis 操作客户端 */ static Jedis jedis = new Jedis("127.0.0.1", 6379);

public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 100; i++) { boolean res = isPeriodLimiting("jiagou1216.com", 3, 10); if (res) { System.out.println("正常访问【https://www.jiagou1216.com】:" + i); } else { System.out.println("限流访问【https://www.jiagou1216.com】:" + i); } } // 休眠 4s Thread.sleep(4000); // 超过最大执行时间之后,再从发起请求 boolean res = isPeriodLimiting("jiagou1216.com", 3, 10); if (res) { System.out.println("休眠后,正常执行请求"); } else { System.out.println("休眠后,被限流"); } }

/** * 限流方法(滑动时间算法/时间窗口算法) * * @param key 限流标识 * @param period 限流时间范围(单位:秒) * @param maxCount 最大运行访问次数 * @return 是否限流 */ private static boolean isPeriodLimiting(String key, int period, int maxCount) { // 当前时间戳 long nowTs = System.currentTimeMillis(); // 删除非时间段内的请求数据(清除老访问数据,比如 period=60 时,标识清除 60s 以前的请求记录) jedis.zremrangeByScore(key, 0, nowTs - period * 1000); // 当前请求次数 long currCount = jedis.zcard(key); if (currCount >= maxCount) { // 超过最大请求次数,执行限流 return false; } // 未达到最大请求数,正常执行业务,请求记录 +1 jedis.zadd(key, nowTs, "" + nowTs); return true; }}

运行main方法

这种方式有两个缺点:

1)使用 ZSet 存储有每次的访问记录,如果数据量比较大时会占用大量的空间,比如60s允许100W访问时;

2)此代码的执行非原子操作,先判断后增加,中间空隙可穿插其他业务逻辑的执行,有可能导致结果不准确。

架构师小跟班,技术类综合网站,是本站长出于个人爱好,搭建的纯公益性质的博客网站,旨在为各位站长,程序员、学生提供免费的开发软件,视频教程,系统源码,网站模板等。

本站做过多次优化,解决了网站打开慢,谷歌浏览器报不安全提示等问题。

本站每周会有多次更新,内容完全免费,尤其是系统源码、毕业设计、视频教程等,没有任何套路,请大胆收藏和推荐

但请粉丝们注意:

本站部分内容是站长从网络搜集所得,没有著作权,请勿用于商业用途,请下载后24小时内删除。谢谢合作!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200521A04A6D00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券