.NET Redis限制接口请求频率 滑动窗口算法
在.NET中使用Redis来限制接口请求频率(每10秒只允许请求一次)
NuGet setup
StackExchange.Redis
实现速率限制逻辑:
在控制器或服务层中,编写Redis速率限制计数器。
设置Redis键:
为每个用户或每个IP地址设置一个唯一的键。这个键将用于存储最后一次请求的时间戳和/请求计数。
检查时间戳:
当请求到达时,从Redis中获取该键的值(时间戳)。如果键不存在或时间戳超过10秒,则允许请求并更新键的值(设置为当前时间戳)。
处理超过速率的请求:
如果时间戳在10秒内,则拒绝或限制该请求(返回限制状态码)。
private static readonly Lazy<ConnectionMultiplexer> LazyConnection = new Lazy<ConnectionMultiplexer>(() =>{// 配置Redis连接字符串 "localhost,abortConnect=false" return ConnectionMultiplexer.Connect("localhost:6379");});private static ConnectionMultiplexer Connection => LazyConnection.Value;private static IDatabase Db => Connection.GetDatabase();public async Task<ActionResult> MyAction(){IPAddress clientIpAddress = HttpContext.Connection.RemoteIpAddress;string ipAddress = clientIpAddress.ToString();string redisKey = $"rate-limit:{ipAddress}"; // 构建Redis键名 // 获取当前时间戳(可以是Unix时间戳或任何你选择的格式) long currentTimestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds();// 尝试从Redis获取时间戳 var redisValue = await Db.StringGetAsync(redisKey);long lastTimestamp = redisValue.HasValue ? (long)redisValue : 0;// 检查是否超过10秒 if (currentTimestamp - lastTimestamp >= 10){// 如果超过10秒,则允许请求并更新Redis键 await Db.StringSetAsync(redisKey, currentTimestamp, TimeSpan.FromSeconds(10)); // 设置键的过期时间为10秒 return Content("Request allowed.");}else{// 如果未超过10秒,则拒绝请求 HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.TooManyRequests){ReasonPhrase = "Too Many Requests",Content = new StringContent("Rate limit exceeded. Please try again later.")};// 处理请求return Content("Please try again later. ");// throw new HttpResponseException(response); // 或者返回自定义的ActionResult }}
扩展为参数
MyAction(string p)
//...
string redisKey = $"rate-limit:{p}";
请求
/MyAction?p=2
/MyAction?p=3
滑动窗口算法
滑动窗口算法(Sliding Window Algorithm)是一种用于解决字符串/数组 问题的算法,它通过维护一个窗口(即一个连续的子串或子数组),并在字符串或数组上滑动这个窗口来寻找满足特定条件的子串或子数组。以下是滑动窗口算法的主要内容和特点:
维护窗口:通过两个指针(左指针和右指针)来定义窗口的边界。
移动窗口:通过移动右指针来扩展窗口,同时根据问题的要求调整左指针来缩小窗口。
更新信息:在窗口滑动的过程中,根据需要更新一些数据结构(如哈希表)来保存所需的信息。
实现方法
步骤1.初始化:定义左指针和右指针,并初始化它们的位置。
步骤2.扩展窗口:向右移动右指针,扩展窗口,同时更新所需的信息(如字符频率的哈希表)。
步骤3.检查条件:当窗口满足特定条件时,开始收缩窗口。
步骤4.收缩窗口:向右移动左指针,缩小窗口,同时更新所需的信息。
步骤5.更新最优解:在收缩窗口的过程中,不断更新最优解(如最长子串、最短子串等)。
重复步骤:重复步骤2到步骤5,直到右指针到达字符串或数组的末尾。
在Redis中维护一个窗口内的请求时间戳列表,而不是仅仅存储最后一次请求的时间戳。移除超过窗口大小的时间戳。检查剩余的时间戳数是否超过了最大请求数 MaxRequests。如果超过,则返回超过的响应;否则,记录当前时间戳并允许请求。
private const int MaxRequests = 5; // 最大请求数private const int WindowSizeInSeconds = 10; // 窗口大小(秒)//...// 获取Redis中存储的时间戳列表var redisValue = await Db.ListRangeAsync(redisKey);var timestamps = redisValue.Select(value => (long)value).ToList();// 移除窗口之外的时间戳timestamps = timestamps.Where(timestamp => currentTimestamp - timestamp <= WindowSizeInSeconds).ToList();if (timestamps.Count >= MaxRequests){// 如果请求数超过限制,则拒绝请求HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.TooManyRequests){ReasonPhrase = "Too Many Requests",Content = new StringContent("Rate limit exceeded. Please try again later.")};return Content("Please try again later.");}else{// 如果请求数未超过限制,则允许请求并记录当前时间戳timestamps.Add(currentTimestamp);await Db.ListRightPushAsync(redisKey, timestamps.Select(timestamp => (RedisValue)timestamp).ToArray());await Db.KeyExpireAsync(redisKey, TimeSpan.FromSeconds(WindowSizeInSeconds)); // 设置键的过期时间为窗口大小return Content("Request allowed.");}
End
相关文章:
.NET Redis限制接口请求频率 滑动窗口算法
在.NET中使用Redis来限制接口请求频率(每10秒只允许请求一次) NuGet setup StackExchange.Redis 实现速率限制逻辑: 在控制器或服务层中,编写Redis速率限制计数器。 设置Redis键: 为每个用户或每个IP地址设置一个唯一…...
Java List数据结构与常用方法
1.1 数据结构概述 Java的集合框架其实就是对数据结构的封装,在学习集合框架之前,有必要先了解下数据结构。 1.1.1 什么是数据结构 所谓数据结构,其实就是计算机存储、组织数据的方式。 数据结构是用来分析研究数据存储操作的,其实…...
Docker搭建redis-cluster集群
1. 前期准备 1.1 拉redis镜像 docker search redis docker pull redis1. 2 创建网卡 docker network create myredis --subnet 172.28.0.0/16#查看创建的网卡 docker network inspect myredisdocker network rm myredis #删除网卡命令 多个中间 空格隔开 docker network --h…...
实验室类管理平台LIMS系统的ui设计实例
实验室类管理平台LIMS系统的ui设计实例...
<PLC><西门子><工控>西门子博图V18中使用SCL语言编写一个CRC16-modbus校验程序
前言 本系列是关于PLC相关的博文,包括PLC编程、PLC与上位机通讯、PLC与下位驱动、仪器仪表等通讯、PLC指令解析等相关内容。 PLC品牌包括但不限于西门子、三菱等国外品牌,汇川、信捷等国内品牌。 除了PLC为主要内容外,PLC相关元器件如触摸屏(HMI)、交换机等工控产品,如…...
Linux - 文件管理高级 find、grep
0.管道 | 将前面命令的标准输出传递给管道作为后面的标准输入 1.文件查找 find find 进行文件查找时,默认进行递归查找,会查找隐藏目录下的文件 1.1 用法 # find 查找路径 查找条件... -type // 文件类型 f 普通文件 b 设备 d …...
DOS编程入门:探索基础、深入技巧与实战应用
DOS编程入门:探索基础、深入技巧与实战应用 DOS编程,作为计算机编程的基石之一,对于初学者来说,既是一种挑战,也是一次深入了解计算机底层运作的绝佳机会。本文将从四个方面、五个方面、六个方面和七个方面࿰…...
创建线程的技术难点
在软件开发中,创建线程并正确地管理它们是一个复杂而关键的任务,涉及的技术难点主要有: 线程同步:当多个线程需要访问共享资源时,必须确保它们以某种方式同步,以避免数据不一致或其他并发问题。例如&#…...
Android ViewPager和ViewPager2的区别
一、实现方式 ViewPager内部是通过继承ViewGroup来实现的,ViewPager2内部是通过RecyclerView来实现的(效率更高) 二、支持方向 ViewPager只能横向滑动,ViewPager2可以横向以及竖向滑动 三、采用的适配器 ViewPager有两个适配…...
Oracle数据库面试题-3
41. 请解释Oracle数据库中的内存顾问(Memory Advisor)的作用。 Oracle 数据库中的内存顾问(Memory Advisor) Oracle 数据库中的内存顾问是一个功能,它可以分析数据库的内存使用情况,并提供优化建议&#…...
21.过拟合和欠拟合示例
1. 背景介绍 在机器学习和深度学习中,过拟合和欠拟合是两个非常重要的概念。过拟合指的是模型在训练数据上表现很好,但在新的测试数据上效果变差的情况。欠拟合则是指模型无法很好地拟合训练数据的情况。这两种情况都会导致模型无法很好地泛化ÿ…...
使用import语句导入模块
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 创建模块后,就可以在其他程序中使用该模块了。要使用模块需要先以模块的形式加载模块中的代码,这可以使用import语句实现。im…...
一台FreeBSD笔记本突然鼠标乱动=>pf防火墙设置@FreeBSD
缘起 一台FreeBSD的笔记本,突然鼠标乱动 思考了下,可能原因有三: 1 无线鼠标干扰 正巧没带鼠标,但是插着无线鼠标usb,不知道是不是别人的鼠标跟这个usb串台了。 2 触摸板机械故障 也许是天热触摸板开始有故障了&…...
身份证OCR识别功能介绍
身份证OCR识别功能是一种基于光学字符识别(OCR)技术的解决方案,专门用于从身份证图像中快速、准确地提取和识别信息。以下是关于身份证OCR识别功能的详细介绍: 功能概述 身份证OCR识别功能通过高分辨率的摄像头或扫描仪获取身份证…...
一文看懂:MES定义和功能是什么,以及在数字化工厂的应用
MES应该是继ERP之后制造企业信息化最热门的管理软件,它适应产品个性化与敏捷化制造需求,满足生产过程精益管理而产生和发展起来的信息系统。 作为企业实现数字化与智能化的核心支撑技术与重要组成部分,MES在帮助制造企业走向数字化、智能化等…...
对 SQL 说“不”~
开发人员注意! 您在当前的应用程序架构中是否面临这些问题? 对 SQL 数据库的高吞吐量。SQL 数据库中的瓶颈。 内存数据存储将是解决问题的方案。Redis 是市场上最受欢迎的内存数据存储和缓存选项。Redis 拥有广泛的生态系统,因为主要科技巨…...
【爱空间_登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞 …...
web前端三大主流框架
一、介绍 目前,前端开发领域的三大主流框架是: React:React是由Facebook开发并维护的开源JavaScript库,用于构建用户界面。它提供了一种声明式的组件化开发方式,能够高效地创建交互性的用户界面。React具有高性能、可…...
git获取的项目无法运行
一、Unsupported engine 问题:在使用命令npm install下载依赖项的时候就遇到了这个问题,有帖子说多试几次,其实这是提示node版本问题,版本的更新出现兼容性问题,多试几次也没用。 解决方案: 更新node.js的…...
java 原生http服务器 测试JS前端ajax访问实现跨域
后端 package Httpv3;import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer;import java.io.IOException; import java.io.OutputStream; import java…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
