我需要为限制请求设计速率限制器服务。 对于每个传入请求,方法将检查每秒请求是否超过其限制。如果超过了它,它将返回等待处理所需的时间。
寻找一个简单的解决方案,它只使用系统滴答计数和rps(每秒请求数)。不应使用队列或复杂的速率限制算法和数据结构。
编辑:我将在c ++中实现它。另外,请注意我不想使用任何数据结构来存储当前正在执行的请求。 API就像:
if(!RateLimiter.Limit()) { 做工作 RateLimiter.Done();
} 其他 拒绝请求
答案 0 :(得分:6)
最常用的算法是token bucket。没有必要发明新的东西,只需要搜索技术/语言的实现。
如果您的应用程序具有高可用性/负载平衡性,您可能希望将存储桶信息保留在某种持久性存储上。 Redis是一个很好的候选人。
我写的Limitd是一种不同的方法,是限制的守护进程。如果流量符合要求,应用程序会使用限制客户端询问守护程序。限制在限制服务器上配置,应用程序与算法无关。
答案 1 :(得分:0)
因为你没有提供任何语言或平台的提示,我只会给出一些伪代码..
你需要的东西
,代码可以像
一样简单var ListOfCurrentRequests; //A list of the start time of current requests
var MaxAmoutOfRequests;// just a limit
var AverageExecutionTime;//if the execution time is non deterministic the best we can do is have a average
//for each request ether execute or return the PROBABLE amount to wait
function OnNewRequest(Identifier)
{
if(count(ListOfCurrentRequests) < MaxAmoutOfRequests)//if we have room
{
Struct Tracker
Tracker.Request = Identifier;
Tracker.StartTime = Now; // save the start time
AddToList(Tracker) //add to list
}
else
{
return CalculateWaitTime()//return the PROBABLE time it will take for a 'slot' to be available
}
}
//when request as ended release a 'slot' and update the average execution time
function OnRequestEnd(Identifier)
{
Tracker = RemoveFromList(Identifier);
UpdateAverageExecutionTime(Now - Tracker.StartTime);
}
function CalculateWaitTime()
{
//the one that started first is PROBABLY the first to finish
Tracker = GetTheOneThatIsRunnigTheLongest(ListOfCurrentRequests);
//assume the it will finish in avg time
ProbableTimeToFinish = AverageExecutionTime - Tracker.StartTime;
return ProbableTimeToFinish
}
但请记住,这个
有几个问题所以理想的解决方案应该是一个实际的执行队列,但是因为你不想要一个......我想这是下一个最好的事情。
答案 2 :(得分:0)
根据你的评论,你只需要一个简单的(不是非常精确的)每秒请求标志。在这种情况下,代码可以是这样的
var CurrentRequestCount;
var MaxAmoutOfRequests;
var CurrentTimestampWithPrecisionToSeconds
function CanRun()
{
if(Now.AsSeconds > CurrentTimestampWithPrecisionToSeconds)//second as passed reset counter
CurrentRequestCount=0;
if(CurrentRequestCount>=MaxAmoutOfRequests)
return false;
CurrentRequestCount++
return true;
}
似乎不是一种非常可靠的控制方法......但是......我相信这就是你所要求的......