ASP.NET Core 的 Web Api 实现限流 中间件
Microsoft.AspNetCore.RateLimiting 中间件提供速率限制(限流)中间件。
它是.NET 7 以上版本才支持的中间件,刚看了一下,确实挺好用,下面给大家简单介绍一下:
RateLimiterOptionsExtensions 类提供下列用于限制速率的扩展方法:
- 固定窗口限制器
- 滑动窗口限制器
- 令牌桶限制器
- 并发限制器
固定窗口限制器
AddFixedWindowLimiter 方法使用固定的时间窗口来限制请求。 当时间窗口过期时,会启动一个新的时间窗口,并重置请求限制。
滑动窗口限制器
滑动窗口算法:
- 与固定窗口限制器类似,但为每个窗口添加了段。 窗口在每个段间隔滑动一段。 段间隔的计算方式是:(窗口时间)/(每个窗口的段数)。
- 将窗口的请求数限制为
permitLimit个请求。 - 每个时间窗口划分为一个窗口
n个段。 - 从倒退一个窗口的过期时间段(当前段之前的
n个段)获取的请求会添加到当前的段。 我们将倒退一个窗口最近过期时间段称为“过期的段”。
令牌桶限制器
令牌桶限制器与滑动窗口限制器类似,但它不会结存从过期段获取的请求数,而是在每个补充期间添加固定数量的令牌。 每个段添加的令牌数不能使可用令牌数超过令牌桶限制。 下表显示了一个令牌桶限制器,其中令牌数限制为 100 个,补充期为 10 秒。
并发限制器
并发限制器会限制并发请求数。 每添加一个请求,在并发限制中减去 1。 一个请求完成时,在限制中增加 1。 其他请求限制器限制的是指定时间段的请求总数,而与它们不同,并发限制器仅限制并发请求数,不对一段时间内的请求数设置上限。
以上介绍是参照微软学习文档,相当枯燥无味,简单总结就是以上限制器都是为了限制客户端频繁请求接口,从而导致服务器压力过大的措施,比如可以防止dos攻击。具体实现直接看代码会比较清楚:
var builder = WebApplication.CreateBuilder(args);builder.WebHost.ConfigureKestrel((context, serverOptions) =>
{serverOptions.Listen(IPAddress.Any, 5000);
});builder.Services.AddRateLimiter(configureOptions =>
{//固定窗口限制器configureOptions.AddFixedWindowLimiter("fixed", options =>{//options.QueueLimit = 1;options.PermitLimit = 3;options.Window = TimeSpan.FromSeconds(10);options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;});//滑动窗口限制器configureOptions.AddSlidingWindowLimiter(policyName: "sliding", options =>{options.PermitLimit = 3;options.Window = TimeSpan.FromSeconds(10);options.SegmentsPerWindow = 1;options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;//options.QueueLimit = 1;});//令牌桶限制器configureOptions.AddTokenBucketLimiter(policyName: "token", options =>{options.TokenLimit = 3;options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;//options.QueueLimit = 1;options.ReplenishmentPeriod = TimeSpan.FromSeconds(10);options.TokensPerPeriod = 2;options.AutoReplenishment = true;});//并发configureOptions.AddConcurrencyLimiter("ConLimit", options =>{options.QueueLimit = 10; //达到并发限制进入队列排队的数量,多余会被丢弃options.PermitLimit = 200;//并发请求最大数量options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;});
});// Add services to the container.
//builder.Services.AddRazorPages();
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();var app = builder.Build();// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{app.UseExceptionHandler("/Error");// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.app.UseHsts();
}
app.UseSwagger();
app.UseSwaggerUI(c => { });app.UseHttpsRedirection();
//app.UseStaticFiles();
//app.UseRouting();app.UseAuthorization();//app.MapRazorPages();
app.MapControllers();//使用限制器
app.UseRateLimiter();//固定窗口限制器
static string GetTicks() => DateTime.Now.ToString("HH:mm:ss");
app.MapGet("/fixed", () => Results.Ok($"固定窗口限制器 {GetTicks()}")).RequireRateLimiting("fixed");
//滑动窗口限制器
app.MapGet("/sliding", () => Results.Ok($"滑动窗口限制器 {GetTicks()}")).RequireRateLimiting("sliding");
//令牌桶限制器
app.MapGet("/token", () => Results.Ok($"令牌桶限制器 {GetTicks()}")).RequireRateLimiting("token");
//并发限制器
app.MapGet("/ConLimit", () => Results.Ok($"并发限制器 {GetTicks()}")).RequireRateLimiting("ConLimit");app.Run();
核心代码就这些:


运行程序,请求http://localhost:5000/fixed ,如果10s内请求大于3次就失败:

10秒后又可以正常访问:

对指定接口进行限制,只需要在指定接口上使用EnableRateLimiting特性就行:
[EnableRateLimiting("sliding")]
[HttpGet]
public string GetString()
{return "111";
}
10秒内请求超3次就失败:

注意上面的 options.QueueLimit 被我注释了,这个主要是设置排队的请求的最大累计允许计数,如果设置了就不会报错而是等待请求,数值是具体可以同时等待的请求数。


相关文章:
ASP.NET Core 的 Web Api 实现限流 中间件
Microsoft.AspNetCore.RateLimiting 中间件提供速率限制(限流)中间件。 它是.NET 7 以上版本才支持的中间件,刚看了一下,确实挺好用,下面给大家简单介绍一下: RateLimiterOptionsExtensions 类提供下列用…...
Mysql字段的各种时间类型
DATE: 特点:存储日期,不包含时间。示例: CREATE TABLE example_date (id INT PRIMARY KEY, event_date DATE ); INSERT INTO example_date (id, event_date) VALUES (1, 2023-01-11); TIME: 特点:存储时间,不包含日…...
Armv8-R AArch32 architecture概念学习
提示 该博客主要为个人学习,通过阅读官网手册整理而来(个人觉得阅读官网的英文文档非常有助于理解各个IP特性)。若有不对之处请参考参考文档,以官网文档为准。阅读该文章,可以先查看AArch64 Exception Model学习&…...
linux手动安装 vscode-server
适用场景 很多时候,我们需要在本机(比如windows)通过remote ssh访问远程服务器(一般是ubuntu),但经常出现 vscode 一直连不上远程服务器的情况,看一下 log: 这个log表示远程服务器…...
【Maven】009-Maven 简单父子工程搭建
【Maven】009-Maven 简单父子工程搭建 文章目录 【Maven】009-Maven 简单父子工程搭建一、需求说明1、结构2、第三方库 二、工程搭建1、父工程第一步:创建父工程第二步:引入公共依赖 lombok 和管理 hutool 依赖版本 2、公共子模块第一步:创建…...
verilog编程题
verilog编程题 文章目录 verilog编程题序列检测电路(状态机实现)分频电路计数器译码器选择器加减器触发器寄存器 序列检测电路(状态机实现) module Detect_101(input clk,input rst_n,input data,o…...
What is `addArgumentResolvers` does in `WebMvcConfigurer` ?
addArgumentResolvers 在SpringMVC框架中,主要用于向Spring容器注册自定义的参数解析器。在处理HTTP请求时,SpringMVC会使用这些参数解析器将请求中的数据(如查询参数、路径变量、表单数据等)转换并注入到控制器方法的参数中。 使…...
[NSSCTF Round#16 Basic]RCE但是没有完全RCE
RCE但是没有完全RCE wp 题目代码: 第一关 <?php error_reporting(0); highlight_file(__file__); include(level2.php); if (isset($_GET[md5_1]) && isset($_GET[md5_2])) {if ((string)$_GET[md5_1] ! (string)$_GET[md5_2] && md5($_GET[m…...
LTD营销枢纽(乐通达)成为杭州市中小企业数字化转型遴选服务商
为推进国家中小企业数字化转型城市试点建设,赋能中小企业信息化、智能化、新型工业化能力水平提升,杭州市经信局公开招募了具备高质量服务能力的中小企业数字化转型服务商。经过公开征集、专家评审等多个环节,LTD营销枢纽凭借其在数字化转型领…...
详细分析Mybatis中的<foreach>标签
目录 前言1. 基本语法2. Demo3. 实际例子 前言 对于Java专栏:Java专栏 对于Mybatis的相关知识可看我之前的文章:Mybatis从入门到精通(全) 对于其余Java框架可看我之前的文章:java框架 零基础从入门到精通的学习路线 附…...
linux-挂载Samba共享
linux-挂载Samba共享 1、linux服务器启动Samba共享服务 2、客户端电脑安装cifs-utils dnf install cifs-utils # 或 yum install cifs-utils3、挂载共享目录 # 创建挂目录 mkdir /share # 使用mount命令挂在共享目录,-t协议类型 -o用户名密码 共享目录访问地址 挂…...
Java入门IDEA基础语法
1:Java入门 1.1 Java简介 Java是什么: Java是一门非常优秀的计算机语言 语言:人与人交流沟通的表达方式 计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言 Java之父:詹姆斯高斯林(James Gosli…...
【小白专用】C# 连接 MySQL 数据库
C# – Mysql 数据库连接 1. 配置环境 #前提:电脑已安装Mysql服务; Visual Studio 安装Mysql依赖库: 工具 -> NuGet 包管理器 -> 管理解决方案的 NuGet程序包 —> 搜索, 安装Mysql.Data (Oracle); (安装成功后&…...
Django登录注销视图
Django在身份验证框架中包含了一些你可以直接使用的表单和视图。在大多数情况下,可以使用默认的Django认证视图。 Django在django.contrib.auth.views提供了以下基于类的视图来处理身份验证: LoginView:处理登录表单并登录用户 LogoutView&a…...
云原生到底是什么意思
云原生到底是什么意思? 引言 随着云计算技术的迅速发展,云原生成为了一个备受关注的话题。云原生不仅仅是一种新的软件架构,更是一种变革性的开发方法论。本文将深入解析云原生的意义、特点以及为什么它在现代软件开发中变得如此重要。 云…...
【银行测试】银行项目,信用卡业务测试+常问面试(三)
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 银行测试-信用卡业…...
AI大模型学习笔记之二:什么是 AI 大模型的训练和推理?
在人工智能(AI)的领域中,我们经常听到训练(Training) 和 推理(Inference) 这两个词汇,它们是构建强大 AI 模型的关键步骤。我们通过类比人类的学习过程来理解这两个概念,可以更加自然而生动地理…...
【MATLAB源码-第113期】基于matlab的孔雀优化算法(POA)机器人栅格路径规划,输出做短路径图和适应度曲线。
操作环境: MATLAB 2022a 1、算法描述 POA(孔雀优化算法)是一种基于孔雀羽毛开屏行为启发的优化算法。这种算法模仿孔雀通过展开其色彩斑斓的尾羽来吸引雌性的自然行为。在算法中,每个孔雀代表一个潜在的解决方案,而…...
iphone 5s的充电时序原理图纸,iPAD充电讲解
上一篇写了iphone 5的时序。那是电池供电的开机时序。iphone 5s也是差不多的过程,不说了。现在看iphone5s手机充电时候的时序。iphone5s充电比iphone5充电简单了很多。 首先是usb接口接到手机上,usb线连接到J7接口上。J7接口不只是接usb,还能…...
react基础入门
1,了解react react并不是一个MVC框架,他只是一个很强大的javaScript库,主要作用是用来构建UI界面。 react的核心是封装一个个大大小小的组件(小到一个按钮,大到一个页面)来构建复杂的UI界面,每…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
