我正在为外部API设计一个.NET客户端应用程序,它将有两个主要职责:
同步 - 定期向API发出一批请求并将响应保存到我的数据库中。
客户端 - 从我的客户端用户那里传递请求到API。
服务文档规定了在给定时间内可以发出的最大请求数量的以下规则:
在白天:
每小时最多6000个请求(约为每秒1.67个)
每分钟最多120个请求(每秒2个)
每秒最多3个请求
在晚上:
每小时最多8000个请求(约为每秒2.23个)
每分钟最多150个请求(每秒2.5个)
每秒最多3个请求
超过这些限制不会立即导致封锁 - 不会抛出任何异常。但是提供者可能会感到恼怒,与我们联系,然后禁止我们使用他的服务。因此,我需要有一些请求延迟机制来防止这种情况发生。以下是我的想法:
最安全和简单的选择是只尊重最低限制,即每2秒最多3个请求。但由于“同步”责任,需要尽可能多地使用这些限制。
因此,下一个选项是根据当前请求计数添加延迟。我已经尝试了自己的一些方法,并且也使用了 David Desmaisons的RateLimiter,这本来没问题,但是有一个问题:
假设我的客户端每天发送3个请求到API,我们将会看到:
- 每120个请求有20秒的延迟 - 每6000个请求有约15分钟的延迟
如果我的应用程序只涉及“同步”,那么这将是可以接受的,但“客户端”请求不能等待那么长时间。
我在网上搜索了有关令牌/漏桶和滑动窗口算法的信息,但由于它们主要涵盖拒绝超过限制的请求,因此我无法将它们翻译成我的情况和.NET。我找到了this repo和that repo,但它们都只是服务端解决方案。
类似QoS的速率分割,使“同步”具有较慢的速率,“客户端”具有较快的速率,不是一个选项。
假设当前请求速率将被测量,如何计算下一个请求的延迟时间,以便它能够适应当前情况,尊重所有最大速率,并且不会超过5秒钟?就像在接近极限时逐渐减速一样。
同步 - 定期向API发出一批请求并将响应保存到我的数据库中。
客户端 - 从我的客户端用户那里传递请求到API。
服务文档规定了在给定时间内可以发出的最大请求数量的以下规则:
在白天:
每小时最多6000个请求(约为每秒1.67个)
每分钟最多120个请求(每秒2个)
每秒最多3个请求
在晚上:
每小时最多8000个请求(约为每秒2.23个)
每分钟最多150个请求(每秒2.5个)
每秒最多3个请求
超过这些限制不会立即导致封锁 - 不会抛出任何异常。但是提供者可能会感到恼怒,与我们联系,然后禁止我们使用他的服务。因此,我需要有一些请求延迟机制来防止这种情况发生。以下是我的想法:
public async Task MyMethod(Request request)
{
await _rateLimter.WaitForNextRequest(); // awaitable Task with calculated Delay
await _api.DoAsync(request);
_rateLimiter.AppendRequestCounters();
}
最安全和简单的选择是只尊重最低限制,即每2秒最多3个请求。但由于“同步”责任,需要尽可能多地使用这些限制。
因此,下一个选项是根据当前请求计数添加延迟。我已经尝试了自己的一些方法,并且也使用了 David Desmaisons的RateLimiter,这本来没问题,但是有一个问题:
假设我的客户端每天发送3个请求到API,我们将会看到:
- 每120个请求有20秒的延迟 - 每6000个请求有约15分钟的延迟
如果我的应用程序只涉及“同步”,那么这将是可以接受的,但“客户端”请求不能等待那么长时间。
我在网上搜索了有关令牌/漏桶和滑动窗口算法的信息,但由于它们主要涵盖拒绝超过限制的请求,因此我无法将它们翻译成我的情况和.NET。我找到了this repo和that repo,但它们都只是服务端解决方案。
类似QoS的速率分割,使“同步”具有较慢的速率,“客户端”具有较快的速率,不是一个选项。
假设当前请求速率将被测量,如何计算下一个请求的延迟时间,以便它能够适应当前情况,尊重所有最大速率,并且不会超过5秒钟?就像在接近极限时逐渐减速一样。