Polly 速率限制过早[重复]

2024-06-19

我正在尝试了解 Polly 的速率限制政策。

public class RateLimiter
{
    private readonly AsyncRateLimitPolicy _throttlingPolicy;
    private readonly Action<string> _rateLimitedAction;

    public RateLimiter(int numberOfExecutions, TimeSpan perTimeSpan, Action<string> rateLimitedAction)
    {       
        _throttlingPolicy = Policy.RateLimitAsync(numberOfExecutions, perTimeSpan);
        _rateLimitedAction = rateLimitedAction;
    }

    public async Task<T> Throttle<T>(Func<Task<T>> func)
    {
        var result = await _throttlingPolicy.ExecuteAndCaptureAsync(func);

        if (result.Outcome == OutcomeType.Failure)
        {
            var retryAfter = (result.FinalException as RateLimitRejectedException)?.RetryAfter ?? TimeSpan.FromSeconds(1);
            _rateLimitedAction($"Rate limited. Should retry in {retryAfter}.");
            return default;
        }

        return result.Result;
    }
}

在我的控制台应用程序中,我正在实例化一个RateLimiter每 10 秒最多 5 次调用。

var rateLimiter = new RateLimiter(5, TimeSpan.FromSeconds(10), err => Console.WriteLine(err));
var rdm = new Random();

while (true)
{
    var result = await rateLimiter.Throttle(() => Task.FromResult(rdm.Next(1, 10)));

    if (result != default) Console.WriteLine($"Result: {result}");

    await Task.Delay(200);
}

我预计会看到 5 个结果,而第 6 个结果的速率会受到限制。但这就是我得到的

Result: 9
Rate limited. Should retry in 00:00:01.7744615.
Rate limited. Should retry in 00:00:01.5119933.
Rate limited. Should retry in 00:00:01.2313921.
Rate limited. Should retry in 00:00:00.9797322.
Rate limited. Should retry in 00:00:00.7309150.
Rate limited. Should retry in 00:00:00.4812646.
Rate limited. Should retry in 00:00:00.2313643.
Result: 7
Rate limited. Should retry in 00:00:01.7982864.
Rate limited. Should retry in 00:00:01.5327321.
Rate limited. Should retry in 00:00:01.2517093.
Rate limited. Should retry in 00:00:00.9843077.
Rate limited. Should retry in 00:00:00.7203371.
Rate limited. Should retry in 00:00:00.4700262.
Rate limited. Should retry in 00:00:00.2205184.

我也尝试过使用ExecuteAsync代替ExecuteAndCaptureAsync并且它并没有改变结果。

public async Task<T> Throttle<T>(Func<Task<T>> func)
{
    try
    {
        var result = await _throttlingPolicy.ExecuteAsync(func);

        return result;
    }
    catch (RateLimitRejectedException ex)
    {
        _rateLimitedAction($"Rate limited. Should retry in {ex.RetryAfter}.");
        return default;
    }
}

这对我来说没有任何意义。我有什么遗漏的吗?


速率限制器的工作方式与您想象的有点不同。

假设我有 500 个请求,我想将其限制为每分钟 50 个。

预期:在前 50 次执行后,如果执行时间少于一分钟,则速率限制器将启动。

这种直观的方法没有考虑输入负载的平均分配。这可能会导致以下可观察到的行为:

  • 假设前 50 次执行花费了 30 秒
  • 然后你还要再等待30秒才能执行第51个请求

Polly 的速率限制器使用漏桶算法 https://en.wikipedia.org/wiki/Leaky_bucket罢工>

其工作原理如下:

  • 桶有固定容量
  • 桶底部有漏水
  • 水滴以给定的频率离开水桶
  • 水桶可以从顶部接收新的水滴
  • 如果传入频率大于传出频率,则存储桶可能会溢出

所以,从技术上来说:

  • 它是一个固定大小的队列
  • 定期调用出队
  • 如果队列已满,则入队会抛出异常

上述描述中最重要的信息如下:漏桶算法使用恒定速率清空桶。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Polly 速率限制过早[重复] 的相关文章

  • 使用 OpenXML 打开受保护的 Word 文档

    我到处寻找 但找不到任何答案 所有帖子和讨论都是关于创建受保护的帖子和讨论 但没有任何内容可以打开它 我在我的 c 程序中保护了 DOCX 和 DOC 文档 并希望使用 OpenXML 2 5 以编程方式打开它们 我已经使用 Office
  • VS2015 代码覆盖率不适用于 ASP.NET Core 1.0(以前称为 ASP.NET 5)中的测试

    我有一个 ASP NET Core 1 0 以前称为 ASP NET 5 解决方案 其中包含几个类库 包 和一个 ASP NET MVC6 项目 我有一个使用支持 Core 1 0 的新 XUnit 2 0 的测试库 然而 由于某种原因 当
  • ExecuteNonQueryAsync 并在 SQL 事务中提交

    我正在寻求对我创建的一段代码的帮助 我正在尝试在事务中从 C 进行异步 SQL 调用 例如我可能正在更新或删除表中的行 这是我到目前为止所拥有的 但我似乎无法找到有关在事务中执行此操作的太多信息 根据我在这里所拥有的以及到目前为止我所理解的
  • 如何防止 Parallel.ForEach 循环在运行时更改任务数量?

    我正在使用Parallel ForEach循环做一些工作 我用localInit像这样 localInit gt new foo new Foo bars CreateBars 根据文档 https learn microsoft com
  • 安装/编译 pylzma(lzma python 绑定)

    我已经向作者提出了这个问题website http www joachim bauch de projects pylzma comment page 1 comment 5211 但我想我也可以在这里问 我一直在尝试使用以下设置安装 py
  • 值类型数组如何存储在 .NET 对象堆中?

    在 NET中 诸如int之类的值类型对象存储在内存中 引用类型对象需要为引用和对象单独分配内存 并且对象存储在 NET对象堆中 而Array是在堆中创建的 那么int 等值类型的数组如何存储在堆中呢 这是否意味着值类型对象可以存储在堆中而无
  • 如何更改控制台中的光标位置?

    我想用Console ReadLine 在上一行中并使其显示如下 HeresomeText gt input Not like HeresomeText gt input 可以做吗 使用 Write 方法而不是 WriteLine 方法 C
  • C#:如何计算纵横比

    我对编程比较陌生 我需要根据给定尺寸 例如 axb 计算纵横比 16 9 或 4 3 我如何使用 C 来实现这一点 任何帮助将不胜感激 public string AspectRatio int x int y code am lookin
  • 更改 Json 中属性的键

    这些天我正在尝试制作一个 json 编辑器 与树视图一起使用 我确实更改了值函数 我也可以更改一些键 但我无法在对象中设置键 我可以设置值 SetValue ref JObject main JToken token JToken newV
  • 为什么未命名的命名空间不等同于带有“using命名空间”声明的常规命名空间?

    A 最近的话题 https stackoverflow com questions 3673353 anonymous namespace ambiguityon SO 触发了这个 未命名的命名空间被认为等同于 namespace uniq
  • “未定义对 clrscr() 的引用;” [复制]

    这个问题在这里已经有答案了 include
  • 在实体框架中不使用 Dispose 或 using()

    我一路上正在编写一个网络应用程序并学习实体框架 如果我做错了什么 我很好奇 我在查询时没有使用过 dispose 或 using 语句 我的存储库示例 public User GetUserById int sessionId var us
  • OpenFileDialog 中的多个文件扩展名

    如何在一组中使用多个文件扩展名OpenFileDialog 我有Filter BMP bmp GIF gif JPG jpg PNG png TIFF tiff 我想创建组 以便 JPG 为 jpg 和 jpeg TIFF 为 tif 和
  • 如何根据条件退出 PostSharp 方面的 OnEntry 方法中的方法

    我希望方面根据如下条件退出方法调用 AttributeUsage AttributeTargets Method public class IgnoreIfInactiveAttribute OnMethodBoundaryAspect p
  • boost::bind 会导致开销吗?

    我目前正在从事网络软件方面的工作 它有一个主要类 server这显然代表一个服务器实例 A server实例可以发送请求 并通过回调通知用户响应 代码如下 class server public typedef boost function
  • 访问控制器类中的 appsettings.json 值

    无法弄清楚如何读取startup cs之外的appsettings json值 例如 我想做的是在 Layout cshtml 中 从配置中添加站点名称 例如 ViewData SiteName Configuration GetValue
  • Pythonlibs3 CMake 和 macOS

    更新2 将以下两行添加到我的 CMake 文件中时 成功找到了 python 3 及其库 这只在终端中工作的原因是因为 CLion 使用其捆绑版本的 CMake 3 6 3 而我的终端使用的更新版本 3 7 2 正确找到了 python F
  • 如何在mvc视图中的表中显示数据库数据

    在我的 MVC 应用程序中 我从数据库检索数据 我想在表格中显示退役数据 控制器代码 public ActionResult MyAccount var user User Identity Name string sThumbnails
  • 我如何在 WPF 中模仿这种行为?

    我对 WPF 和 C 开发相当陌生 我正在制作这个应用程序 我不知道是否有人熟悉 VOIP App Discord 但他们有一个我非常喜欢的特定行为 并且想尝试使用 WPF 创建类似的风格 当您在 Discord 上添加服务器时 单击一个按
  • SQlite 查询 - 如何检索多列数据?

    我很难在网上找到一个关于使用 xcode 和 cocos2dx 从 SQlite DB 获取多个值的工作示例 这是我的sql查询 char sql query 100 sprintf sql query SELECT FROM SQList

随机推荐