限制对资源的访问

本文关键字:访问 资源 | 更新日期: 2023-09-27 18:28:54

我想知道如何为需要节流的REST服务实现包装器。该服务的费率限制为"每分钟最多60个电话"或类似的费率。过度使用资源意味着我的客户端被阻塞了很长一段时间,所以我必须注意不要让这种情况发生,因此我希望包装器本身受到速率限制。

编辑:删除了最后的想法,并将其作为答案

限制对资源的访问

发布

受@Alex评论的启发,回答我自己的问题时,这个解决了时间跨度T中最多N个请求的问题。它将最后N个请求保存在一个列表(循环缓冲区)中,如果最旧的调用早于T,则允许请求。

public class Throttler<T>
{
   private readonly long[] callTimes;
   private int cur;      
   private readonly Func<T> func;
   private readonly TimeSpan interval;
   private readonly object padlock = new object();    
   public Throttler(Func<T> func, int maxCalls, TimeSpan interval)
   {
      this.func = func;
      callTimes = new long[maxCalls];
      this.interval = interval;
      cur = 0;
   }
   public T Call()
   {
      lock (padlock)
      {
         do
         {
            long oldestCall = callTimes[(cur + 1)%callTimes.Length];
            long now = DateTime.UtcNow.Ticks;               
            if (now - oldestCall > interval.Ticks)
            {                 
               cur = (cur + 1) % callTimes.Length;                  
               callTimes[cur] = now;
               return func();
            }
            int sleepTime = (int)((interval.Ticks - (now - oldestCall))/TimeSpan.TicksPerMillisecond) + 1;               
            Thread.Sleep(sleepTime);               
         } while (true);
      }
   }
}