FireflySoft.RateLimit 使用

本文介绍了FireflySoft.RateLimit限流组件的使用方法。创建限流处理器需提供被限流请求类型、限流算法和规则等信息,该组件提供四种限流算法。限流计数可保存在内存或Redis中,还可设置限流错误信息和锁定时间。同时给出了ASP.NET Core和ASP.NET的使用示例。

限流处理器

使用FireflySoft.RateLimit首先需要创建一个限流处理器RateLimitProcessor的实例,然后用它来过滤每一个请求。创建RateLimitProcessor的实例,至少需要提供两个信息:被限流的请求类型、限流算法和规则。其它还有限流计数持久化方式、限流错误信息,如果不提供会使用默认值。这里先不展开,后边会详细介绍它们。创建RateLimitProcessor需要采用构造器模式,如果你使用ASP.NET Core应该很熟悉,如果没什么印象打开Program.cs就可以看到了。为了提高效率,这个限流处理器一般会统一放在某个过滤器中,这个过滤器在ASP.NET中可以是一个消息处理器,在ASP.NET Core中一般就是一个中间件。为了方便集成,FireflySoft.RateLimit已经提供了一个基于ASP.NET的消息处理器和一个基于ASP.NET Core的中间件,通过Github和Nuget都可以很方便的找到他们,Github上还提供了演示程序.

被限流请求类型

被限流请求类型就是需要被限制的业务请求的类型,在ASP.NET中他可能是HttpRequestMessage,在ASP.NET Core中它可能是HttpContext,在其它业务中它可能是你自定义的一个类型XXXRequest。被限流请求类型很重要,因为不同的业务可能使用不同的请求类型,而限流处理程序需要从当前请求中提取或关联到限流目标,明确请求类型才能确定提取方法,否则对请求进行限制将无所适从

限流算法和规则

FireflySoft.RateLimit提供了四种常见的限流算法:固定窗口、滑动窗口、漏桶、令牌桶。固定窗口相对最简单,无论是算法的时间复杂度还是分布式环境实现难度都比较有优势,如果需求是在较短的时间内进行限制,比如每秒限制多少次,使用这种算法是最合适的。但是实际场景中请求在时间分布中可能不太均匀,时多时少,根据需求的不同,可能需要选择其它三种限流算法,这里不做说明了,网上已经有很多的场景选择说明。 初始化限流算法还需要提供对应的限流规则,因为不同的算法往往需要不同的参数,这里很难对不同的算法提供完全统一的限流规则,不过这些规则确实是有共同设置项的,比如限流锁定时间、目标提取方法、是否应用限流处理的判断方法等。 以上文【使用方法】中的限流代码为例,做一些介绍:

  1. FixedWindowAlgorithm是此限流组件提供的固定窗口限流算法。

  2. FixedWindowRateLimitRule是此限流组件提供的固定窗口限流规则类型;

  3. HttpContext是业务中需要限制的请求类型,这里是Http请求上下文类型;

  4. StatWindow是固定窗口的大小,是一个时间跨度;

  5. LimitNumber是限流值,在StatWindow时间内请求数超过它就会触发限流;

  6. LockSeconds是触发限流后的锁定时间,此时间内请求都会被阻止,不需要锁定时可以不设置;

  7. ExtractTarget传递一个方法用于从请求中提取限流目标,这里是用户的每一个请求路径;

  8. CheckRuleMatching传递一个方法用于检查当前请求是否需要限流检查,这里return true代表所有请求都要经过限流检查。

这里有两个比较有意思的设置:ExtractTargetCheckRuleMatching,他们共同作用,让用户可以完全自由的定制自己限流的目标和条件,不固定是IP、ClientId或者Url。其它算法规则中每个设置项的含义可以通过其注释了解到。 如果这几个算法还不能满足要求,可以通过实现IRateLimitAlgorithm来定义一个新的算法。

计数持久化方式

FireflySoft.RateLimit中的限流计数目前支持保存在内存或者Redis中,也可以通过实现IRateLimitStorage来定义一个新的存储器。 对于只需要部署一份的程序,绝大部分情况下使用内存就够了;但是如果限流的时间窗口比较长,比如1小时限制300次,重启就会丢失计数,这可能是个风险,此时使用Redis会比较合适。 对于需要部署多份的程序,如果请求是基本均匀的,并且在每个部署之间的分配也是均匀的,那么使用内存存储器也未尝不可,将总的限流数平均分配在每一个部署中,只要有一个部署触发限流,其它部署很大几率上也会触发限流。但是对于需要部署多份的情况,采用更持久的Redis方式才是稳妥的。 相比内存访问,Redis访问需要网络交互,这会造成一定的性能损失,访问量很大时也会产生拥堵,不过也可以将请求分散到多个Redis的方式进行缓解;同时分布式环境下数据一致性的实现难度更大,即使使用Redis,比如限流处理中必然会涉及的各种时间,不同节点之间的时间不可能绝对一致,越短的时间窗口协调难度越大。因此使用滑动窗口、漏桶、令牌桶等分布式实现难度较大的算法时,需要注意时间单位的设置.

限流错误信息

限流错误信息是触发限流时限流检查结果中附带的信息,目前每个限流处理器允许设置一个统一的RateLimitError,方便业务侧进行统一处理。默认限流错误Code是429,Message为null。你也可以不使用这个定义的值,根据当前限流目标和限流规则构造自己的错误信息

限流锁定

限流锁定是触发限流时的惩罚性处理。FireflySoft.RateLimit通过设置限流规则中的LockSeconds,定义触发限流后的锁定时间,此时间内的请求都会被认定触发限流规则,而不被允许通过;如果不需要锁定忽略这个设置就可以了

如上图所示,时间单位是1秒,阈值是3。

  • 第1秒3个请求,不会触发限流;

  • 第2秒1个请求,不会触发限流;

  • 第3秒4个请求,这一秒的前3个请求正常处理,第4个请求触发限流,会被拒绝处理。

  • 后续第4秒、第5秒不会触发限流,所有请求正常处理。

Core、AspNet、Middleware 3种

Github 源码地址

GitHub - bosima/FireflySoft.RateLimit: It is a rate limiting library based on .Net standard.

ProjectDescriptioin
FireflySoft.RateLmit.CoreFireflySoft.RateLmit的算法、规则、持久化和其它核心代码。
FireflySoft.RateLimit.AspNet为基于 .NET Framework的ASP.NET提供的限流组件。
FireflySoft.RateLimit.AspNetCoreASP.NET Core限流中间件。
FireflySoft.RateLimit.Core.UnitTestUnit test for FireflySoft.RateLimit.Core.
FireflySoft.RateLimit.Core.BenchmarkTestBenchmark test for FireflySoft.RateLimit.Core.
samples/consoleFireflySoft.RateLmit.Core sample program.
samples/aspnetFireflySoft.RateLimit.AspNet sample program.
samples/aspnetcoreFireflySoft.RateLimit.AspNetCore sample program.
samples/aspnetcore6FireflySoft.RateLimit.AspNetCore with .NET6 sample program.

ASP.NET Core 使用方法:

1、Install Nuget Package Package Manager: Install-Package FireflySoft.RateLimit.AspNetCore Or .NET CLI: dotnet add package FireflySoft.RateLimit.AspNetCore

Use Middleware 使用方法:

public void ConfigureServices(IServiceCollection services) { ...

services.AddRateLimit(new InProcessFixedWindowAlgorithm(
    new[] {
        new FixedWindowRule()
        {
            ExtractTarget = context =>
            {
                return (context as HttpContext).Request.Path.Value;
            },
            CheckRuleMatching = context =>
            {
                return true;
            },
            Name="default limit rule",
            LimitNumber=30,
            StatWindow=TimeSpan.FromSeconds(1)
        }
    })
);
​
...

}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ...

app.UseRateLimit();
​
...

}

ASP.NET

1、Install Nuget Package:

Install-Package FireflySoft.RateLimit.AspNet

2、Register MessageHandler

Open Global.asax.cs, the following code adds the rate limit message handle:

protected void Application_Start() { ...

GlobalConfiguration.Configuration.MessageHandlers.Add(
    new RateLimitHandler(
        new Core.InProcessAlgorithm.InProcessFixedWindowAlgorithm(
            new[] {
                new FixedWindowRule()
                {
                    ExtractTarget = context =>
                    {
                        return (context as HttpRequestMessage).RequestUri.AbsolutePath;
                    },
                    CheckRuleMatching = context =>
                    {
                        return true;
                    },
                    Name="default limit rule",
                    LimitNumber=30,
                    StatWindow=TimeSpan.FromSeconds(1)
                }
            })
    ));
​
...

}

<think>我们有一个目标:将提供的ADB命令序列写成一个可以直接运行的BAT脚本文件。 提供的ADB命令序列: @echo off adb shell setprop persist.log.ratelimit 0 adb shell stop adb shell start adb shell getprop persist.log.ratelimit pause 注意:这个命令序列中已经包含了BAT脚本的常用指令(@echo off, pause),所以我们只需要将其保存为.bat文件即可。 但是,根据引用[1]的提示,如果环境变量没有配置,我们需要先切换到adb所在的目录。因此,我们可以有两种处理方式: 1. 假设用户已经配置了环境变量,那么直接使用adb命令。 2. 如果没有配置环境变量,则需要在脚本中切换到adb所在目录(如:cd C:\android-sdk\platform-tools)。 另外,根据引用[2]的提示,当需要执行多条adb shell命令时,我们可以通过生成临时文件的方式输入多条命令。但是在这个脚本中,我们并没有在同一个shell中执行多条命令,所以不需要那样做。 因此,我们可以这样写: 步骤: 1. 创建一个新的文本文件。 2. 将以下内容复制进去(注意:如果用户没有配置环境变量,需要先cd到adb所在目录,这里我们提供一种通用的方式,让用户自行修改路径)。 3. 保存为.bat文件(例如:disable_log_rate_limit.bat)。 脚本内容如下: 注意:由于我们不知道用户的环境变量配置情况,我们可以提供两种方式: 方式一:直接使用adb命令(适用于已配置环境变量) 方式二:先切换目录再执行(适用于未配置环境变量) 我们可以让用户根据情况修改脚本,或者我们写一个通用的脚本,先尝试直接执行,如果失败再提示用户修改。 但是,为了简单,我们可以在脚本中注释说明,让用户自行修改路径。 以下是脚本内容:</think>### 如何将 ADB 命令写入 BAT 脚本并直接运行 以下是完整的 BAT 脚本解决方案,实现日志速率限制的修改和验证: ```batch @echo off REM ===== 配置 ADB 路径(未配置环境变量时需修改)===== set ADB_PATH=C:\android-sdk\platform-tools\adb.exe REM ===== 验证设备连接状态 ===== %ADB_PATH% devices | find "device" > nul if %errorlevel% neq 0 ( echo 错误:未检测到已连接的Android设备 echo 请确认:1. USB调试已开启 2. 设备已授权 pause exit /b 1 ) REM ===== 核心命令执行 ===== echo 正在修改日志速率限制... %ADB_PATH% shell setprop persist.log.ratelimit 0 echo 重启系统服务... %ADB_PATH% shell stop timeout /t 2 > nul %ADB_PATH% shell start timeout /t 3 > nul REM ===== 结果验证 ===== echo 验证配置状态... %ADB_PATH% shell getprop persist.log.ratelimit > result.txt set /p RATE_LIMIT=<result.txt del result.txt if "%RATE_LIMIT%"=="0" ( echo ✓ 配置成功!当前日志速率限制:0(无限制) ) else ( echo ✗ 配置失败!返回值:%RATE_LIMIT% echo 可能原因:1. 设备未ROOT 2. 系统权限限制 ) REM ===== 日志服务额外重启(增强兼容性)===== echo 重启日志服务... %ADB_PATH% shell killall logd > nul 2>&1 timeout /t 1 > nul pause ``` #### 使用说明: 1. **保存文件** 将代码复制到文本编辑器,保存为 `.bat` 文件(如 `disable_log_limit.bat`) 2. **环境适配**(二选一): - 已配置 ADB 环境变量:删除 `set ADB_PATH=...` 行 - 未配置变量:修改路径为你的 ADB 实际位置(参考引用[1]) 3. **执行脚本**: - 双击运行或命令行执行 `.bat` 文件 - 连接 Android 设备并开启 USB 调试(需授权) #### 脚本特性: 1. **错误处理** 自动检测设备连接状态(避免空操作) 2. **延时控制** 使用 `timeout` 确保服务重启完成(参考引用[4]) 3. **结果验证** 解析并显示配置结果(成功/失败状态) 4. **兼容性增强** 额外重启 `logd` 服务(应对部分定制 ROM) #### 执行效果示例: ```powershell 正在修改日志速率限制... 重启系统服务... 验证配置状态... ✓ 配置成功!当前日志速率限制:0(无限制) 重启日志服务... 请按任意键继续... ``` > 💡 **提示**:如需自动化测试(如引用[2][3]),可在脚本末尾添加: > ```batch > adb logcat -v time > log_%date:~0,4%%date:~5,2%%date:~8,2%.txt > ``` > 这将导出带时间戳的完整日志 --- ### 📚 相关问题 1. 如何批量在多台设备上执行此脚本? 2. BAT 脚本中如何捕获和处理 ADB 命令的错误输出? 3. 除了日志限制,还有哪些常用系统属性可通过 ADB 修改? 4. 如何实现无人值守的自动化 ADB 脚本执行(不显示CMD窗口)? [^1]: 环境变量配置参考 [^2]: 复杂命令执行方法 [^3]: ADB 自动化测试场景 [^4]: 命令输出重定向技术
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值