我正在开发一个与web服务API接口的Python库。像我遇到的许多web服务一样,这一个请求限制了请求的速率。我想为类实例化提供一个可选参数limit
,如果提供了这个参数,它将保持传出请求,直到指定的秒数通过为止。
我知道一般情况如下:类的实例通过方法发出请求。当它这样做时,该方法发出一些信号,在某处设置一个锁变量,并在limit
中为秒数开始倒计时。(很可能,锁本身就是倒计时计时器。)如果在此时间范围内发出另一个请求,则必须将其排队,直到倒计时计时器达到零并且锁被解除;此时,队列上最早的请求被发送,并且倒计时计时器被重置,锁被重新启用。
这是穿线的箱子吗?有没有别的方法我看不到?
倒计时计时器和锁应该是实例变量,还是应该属于类,以便类的所有实例都持有请求?
另外,在库中提供速率限制功能通常是个坏主意吗?我的理由是,由于在默认情况下,倒计时是零秒,库仍然允许开发人员使用库并提供自己的速率限制方案。但是,考虑到使用该服务的任何开发人员无论如何都需要限制请求的速率,我认为库提供速率限制的方法将是一种便利。
无论是否在库中放置速率限制方案,我都希望使用库编写应用程序,因此建议的技术将派上用场。
非常感谢你的建议!
克里斯
有了队列和调度程序,效果会更好。
您将处理分为两个方面:源和调度。它们可以是单独的线程(如果更容易的话,可以是单独的进程)。
源代码端以任何速率创建和排队请求,使它们满意。
调度方这样做。
获取请求开始时间,s。
将请求出列,通过远程服务处理请求。
得到当前时间,t。睡眠时间rate-(t-s)秒。
如果要运行直接连接到远程服务的源端,可以这样做,并绕过速率限制。这对于使用模拟版本的远程服务进行内部测试很好。
这方面的难点在于为每个可以排队的请求创建一些表示。因为PythonQueue几乎可以处理任何事情,所以您不必做太多工作。
如果使用多处理,则必须pickle将对象放入管道中。
排队可能过于复杂。一个更简单的解决方案是为您的类提供上次调用服务时的变量。无论何时调用服务(!1) ,将waitTime设置为
delay - Now + lastcalltime
。delay
应等于请求之间允许的最短时间。如果这个号码是肯定的,在打电话之前要睡那么长时间(!2) 是的。这种方法的缺点/优点是它将web服务请求视为同步的。其优点是它非常简单且易于实现。当然,S.Lott的解决方案更优雅。
您的速率限制方案应该受到底层代码(同步或异步)的调用约定以及什么范围(线程、进程、机器、集群?)这个速率限制将在。
我建议将所有变量都保存在实例中,这样就可以轻松地实现多个时段/控制率。
最后,听起来你想成为一个中间件组件。不要试图成为一个应用程序,而要自己引入线程。如果您是同步的,只需阻塞/睡眠;如果您被其中一个调用,则使用异步调度框架。
相关问题 更多 >
编程相关推荐