VKProxy新增速率限制功能
VKProxy 是使用c#开发的基于 Kestrel 实现 L4/L7的代理(感兴趣的同学烦请点个github小赞赞呢)
目前新添加了速率限制(限流)功能
什么是速率限制?
速率限制是限制可以访问的资源量的概念。 例如,你可能知道应用访问的数据库每分钟可以安全地处理 1,000 个请求,但它可能处理不了更多。 可以在应用中放置一个速率限制器,每分钟只允许 1,000 个请求,并在它们可以访问数据库之前拒绝更多请求。 因此,限制数据库速率并允许应用处理安全数量的请求。 这是分布式系统中的一种常见模式,其中你可能有多个应用实例正在运行,并且你希望确保它们不会同时尝试访问数据库。 有多个不同的速率限制算法来控制请求流。
在 .NET 中已经提供相关实现,可使用 System.Threading.RateLimiting NuGet 包。
VKProxy 也是基于其提供速率限制功能,不过相关实现都只是单实例内部计数,没有分布式的实现,毕竟分布式计数可能导致复杂度和性能下降。
ASP.NET Core中如何使用可参见ASP.NET Core 中的速率限制中间件
为何使用速率限制
速率限制可用于管理向应用发出的传入请求流。 实现速率限制的关键原因:
- 防止滥用:速率限制通过限制用户或客户端在给定时间段内发出的请求数来帮助保护应用免受滥用。 这对于公共 API 尤其重要。
- 确保公平使用:通过设置限制,所有用户都可以公平地访问资源,防止用户垄断系统。
- 保护资源:速率限制通过控制可处理的请求数来帮助防止服务器重载,从而防止后端资源过载。
- 增强安全性:它可以通过限制处理请求的速度来缓解拒绝服务(DoS)攻击的风险,从而使攻击者更难淹没系统。
- 提高性能:通过控制传入请求的速度,可以维护应用的最佳性能和响应能力,确保更好的用户体验。
- 成本管理:对于基于使用情况产生成本的服务,速率限制可以通过控制处理的请求量来帮助管理和预测费用。
速率限制已经是API Gateway标配功能,所以VKProxy也得有
防止 DDoS 攻击
虽然速率限制通过限制处理请求的速率来帮助缓解拒绝服务(DoS)攻击的风险,但它不是分布式拒绝服务(DDoS)攻击的综合解决方案。 DDoS 攻击涉及多个系统,使应用遭受大量请求,因此难以单独处理速率限制。
对于可靠的 DDoS 保护,请考虑使用商业 DDoS 保护服务。 这些服务提供高级功能,例如:
- 流量分析:持续监视和分析传入流量,实时检测和缓解 DDoS 攻击。
- 可伸缩性:通过跨多个服务器和数据中心分布流量来处理大规模攻击的能力。
- 自动缓解:自动响应机制,无需手动干预即可快速阻止恶意流量。
- 全球网络:一个全局服务器网络,用于吸收和缓解离源更近的攻击。
- 不断更新:商业服务持续跟踪和更新其保护机制,以适应新的和不断演变的威胁。
使用云托管服务时,DDoS 防护通常作为托管解决方案的一部分提供,例如 Azure Web 应用程序防火墙、 AWS 防护 或 Google Cloud Armor。 专用保护可用作 Web 应用程序防火墙(WAF)或 CDN 解决方案的一部分,例如 Cloudflare 或 Akamai Kona Site Defender
结合速率限制实施商业 DDoS 保护服务可以提供全面的防御策略,确保应用的稳定性、安全性和性能。
速率限制器算法
目前VKProxy提供四种速率限制
Concurrency
并发FixedWindow
固定窗口SlidingWindow
滑动窗口TokenBucket
令牌桶
Concurrency
并发
并发限制器会限制并发请求数。 每添加一个请求,在并发限制中减去 1。 一个请求完成时,在限制中增加 1。 其他请求限制器限制的是指定时间段的请求总数,而与它们不同,并发限制器仅限制并发请求数,不对一段时间内的请求数设置上限。
配置举例
appsettings.json
{
"ReverseProxy": {
"Routes": {
// Routes id : httpTestRoute
"httpTestRoute": {
"Limit": {
"Policy": "Concurrency",
"By": "Total", // 整个路由采用同一份速率控制,无论不同ip还是不同用户
"PermitLimit": 10, // 在同时租用的最大许可证数。
"QueueLimit": 0 // 当已达限制时可同时排队的最大许可数。当为 0 时,表示禁止队列
},
}
}
}
}
ui
FixedWindow
固定窗口
使用固定的时间窗口来限制请求。 当时间窗口过期时,会启动一个新的时间窗口,并重置请求限制。
配置举例
appsettings.json
{
"ReverseProxy": {
"Routes": {
// Routes id : httpTestRoute
"httpTestRoute": {
"Limit": {
"Policy": "FixedWindow",
"By": "Key", // 根据 header 提供提供不同的速率控制计数
"Header": "X-forwarded-For", // 根据cdn 的客户端真实ip区分, 不同cdn 会有不同ip header , 没有值时会默认采用 `RemoteIpAddress`
"PermitLimit": 10, // 在同时租用的最大许可证数。
"QueueLimit": 2, // 当已达限制时可同时排队的最大许可数。当为 0 时,表示禁止队列
"Window": "00:00:10" // 指定补货之间的最短期限
},
}
}
}
}
ui
SlidingWindow
滑动窗口
滑动窗口算法:
- 与固定窗口限制器类似,但为每个窗口添加了段。 窗口在每个段间隔滑动一段。 段间隔的计算方式是:(窗口时间)/(每个窗口的段数)。
- 将窗口的请求数限制为 permitLimit 个请求。
- 每个时间窗口划分为一个窗口 n 个段。
- 从倒退一个窗口的过期时间段(当前段之前的 n 个段)获取的请求会添加到当前的段。 我们将倒退一个窗口最近过期时间段称为“过期的段”。
请考虑下表,其中显示了一个滑动窗口限制器,该限制器的窗口为 30 秒、每个窗口有三个段,且请求数限制为 100 个:
- 第一行和第一列显示时间段。
- 第二行显示剩余的可用请求数。 其余请求数的计算方式为可用请求数减去处理的请求数和回收的请求数。
- 每次的请求数沿着蓝色对角线移动。
- 从时间 30 开始,从过期时间段获得的请求会再次添加到请求数限制中,如红色线条所示。
配置举例
appsettings.json
{
"ReverseProxy": {
"Routes": {
// Routes id : httpTestRoute
"httpTestRoute": {
"Limit": {
"Policy": "SlidingWindow",
"By": "Key", // 根据 Cookie 提供提供不同的速率控制计数
"Cookie": "sessionid", // 根据Cookie的sessionid 区分, 没有值时会默认采用 `RemoteIpAddress`
"PermitLimit": 10, // 在同时租用的最大许可证数。
"QueueLimit": 2, // 当已达限制时可同时排队的最大许可数。当为 0 时,表示禁止队列
"Window": "00:00:10", // 指定补货之间的最短期限
"SegmentsPerWindow": 2 // 指定窗口划分到的最大段数。
},
}
}
}
}
ui
TokenBucket
滑动窗口
令牌桶限流器与滑动窗口限制器类似,但是它并不重新添加来自过期段的请求,而是在每个补充周期内一次性补充固定数量的令牌。 每个段添加的令牌数不能使可用令牌数超过令牌桶限制。 下表显示了一个令牌桶限制器,其中令牌数限制为 100 个,补充期为 10 秒。
配置举例
appsettings.json
{
"ReverseProxy": {
"Routes": {
// Routes id : httpTestRoute
"httpTestRoute": {
"Limit": {
"Policy": "TokenBucket",
"By": "Total", // 整个路由采用同一份速率控制,无论不同ip还是不同用户
"PermitLimit": 10, // 存储桶中随时可以包含的最大令牌数。
"QueueLimit": 2, // 当已达限制时可同时排队的最大许可数。当为 0 时,表示禁止队列
"Window": "00:00:10", // 指定补货之间的最短期限
"TokensPerPeriod": 2 // 指定用于还原每次补充的最大令牌数
},
}
}
}
}
ui
asp.net core 可以直接使用官方中间件
如按 IP 地址分区 (详细可参见ASP.NET Core 中的速率限制中间件)
using Microsoft.AspNetCore.RateLimiting;
using System.Threading.RateLimiting;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRateLimiter(i =>
{
i.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
RateLimitPartition.GetFixedWindowLimiter(
partitionKey: httpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown",
factory: _ => new FixedWindowRateLimiterOptions
{
PermitLimit = 50,
Window = TimeSpan.FromMinutes(1),
QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
QueueLimit = 2
}));
});
var app = builder.Build();
app.UseRateLimiter();
static string GetTicks() => (DateTime.Now.Ticks & 0x11111).ToString("00000");
app.MapGet("/", () => Results.Ok($"Hello {GetTicks()}"));
app.Run();
VKProxy新增速率限制功能的更多相关文章
- 更新日志 - BugHD 新增邮件告警功能
最近 BugHD 又新增了一些功能,包括邮件告警. issue 分享. issue 备注等,同时也做了性能优化.希望能够帮助你更高效地收集解决应用崩溃. BugHD 新增功能 1.邮件告警 除了 We ...
- RDIFramework.NET V3.3 Web框架主界面新增横向菜单功能
功能描述 响应重多客户的要求与心声,RDIFramework.NET框架Web版本主界面新增横向菜单功能.横向菜单更加直观,用户可操作与展示的空间更多,符合实际应用要求. 一.效果展示 最终界面效果: ...
- Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币
什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...
- 咏南中间件新增MORMOT插件功能
咏南中间件新增MORMOT插件功能 咏南中间件支持DATASNAP和MORMOT两种通讯框架. 原来已经支持DATASNAP插件,现在又增加了MORMOT插件,已经支持DATASNAP和MORMOT两 ...
- ABBYY FineReader 15新增编辑页面布局功能
ABBYY FineReader 15(Windows系统) 新增编辑页面布局功能,允许用户修改PDF数字文档的页面布局,包括添加或者删除文字段落,文字块以及图片,更改段落,文字块,图片位置.添加或者 ...
- Windows Server 2016-DNS 新增或改进功能
本章节补充介绍在 Windows Server 2016 中域名系统 (DNS) 服务器新增或已更改的功能相关信息,具体内容如下: 功能 新增或改进 描述 DNS 策略 新增 您可以配置 DNS 策略 ...
- JavaScript学习笔记-商品管理新增/删除/修改功能
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- 百度地图 api 功能封装类 (ZMap.js) 新增管理事件功能 [源码下载]
ZMap 功能说明 ZMap.js 本类方法功能大多使用 prototype 原型 实现: 包含的功能有:轨迹回放,圈画区域可编辑,判断几个坐标是否在一个圆圈内,生活服务查询,从经纬度获取地址信息,地 ...
- RDIFramework.NET V3.3 Web版新增报表管理功能模块-重量级实用功能
功能描述 在RDIFramework.NET V3.3 Web版本新增了全新的报表管理功能模块,非常实用的功能,重量级推荐.主要用于对日常常用的报表做定制展示.可以自动发布到模块(就可授权给指定资源访 ...
- RDIFramework.NET V3.3 Web版新增日程管理功能模块
功能描述 在RDIFramework.NET V3.3 Web版本我们新增了日程管理.基于月.周.日的日历视图,把安排到每一天的具体时间点,让每一天的时间都充分利用:甚至您也可以把个人非工作事项也安排 ...
随机推荐
- MUX-VLAN
MUX VLAN(Multiplex VLAN)是一种高级的VLAN技术,它通过在交换机上实现二层流量隔离和灵活的网络资源控制,提供了一种更为细致的网络管理方式. 一.基本概念 MUX VLAN分为主 ...
- IDEA 使用GIt提交代码时,如果不小心提交了不需要提交的内容,在本地仓库中,此时需要回滚版本,如何回滚
选择上次提交的提交记录 选择上次提交的提交记录复制版本号 选中项目的Git重置器 填入刚复制的回滚版本号-点击Reset 这样一来就回滚回去了,本地提交就没了
- GPU CPU运算时间测试
GPU CPU运算时间测试 本文主要探讨GPU,CPU在做一些复杂运算的时间测试 实验任务 1.向量加法 两个相同维度的向量a,b做加法,分别测试GPU并行时间(包含数据拷贝时间),CPU串行时间. ...
- ISODate时间转换
private function formatISODate($dateTime) { $date = date("Y-m-d", strtotime($dateTime)); $ ...
- springboot和jdk的版本对应关系
spring-boot和jdk的版本对应关系 SpringBoot Versions JDK Versions 0.0 -1.1 6+(6 or higher) 1.2 - 1.5 6 - 7 2.0 ...
- C#+Appium+Nunit实现app自动化demo
1.新建Nunit工程 打开Rider新建一个Nunit工程并使用NuGet安装对应库,步骤如下: 2.编写代码 代码如下: using System; using NUnit.Framework; ...
- eolinker校验规则之 Json结构定位:返回结果校验的方法和案例(父参、子参内容校验)
如下图,订单编号的参数在data父字段内 Eolinker返参校验的写法就需要有些变化 先写Data父参,添加子字段,再写子参 预期结果不支持全局变量 可通过添加绑定,绑定前一个接口返回参数,进行匹配
- 基于Vosk与Transformers的会议摘要生成系统实战教程
一.项目背景与价值 在现代办公场景中,会议记录与摘要生成是提升工作效率的重要环节.传统人工记录方式存在效率低.易遗漏等问题,而基于AI的解决方案可以实时转录会议内容并生成结构化摘要.本教程将指导开发者 ...
- Vue3 中的5种常见的组件传值方式,Vue3事件总线(无需插件)
Vue3 中常见的组件传值方式: Props:这是 Vue 中最常见的组件传值方式,即在父组件中定义 prop 并将数据传递给子组件. Event Bus:可以通过事件总线在两个组件之间进行通信,即定 ...
- Linux操作系统(中)
上一篇分享了一些Linux操作系统最基本的一些命令和基础知识,下面,要分享的还是Linux操作系统的一些内容,因为在做网安这方面,Linux会经常用到而且也很重要,好了,废话不多说,要开始了. 在Li ...