限制每x秒发送的CFHTTP请求数



我正在制作一个应用程序,该应用程序将不断向服务器发送CFHTTP请求以搜索项目,并发送更多的CFHTTP请求来对任何返回的结果执行操作。

我遇到的问题是,服务器的最大阈值是每秒3个请求,即使我尝试每4毫秒实现一次睡眠调用,它也无法正常工作,因为尽管它会延迟,但如果需要几秒钟才能返回,CFHTTP请求可能会排队,因此它会尝试在同一秒内发送多个请求,从而触发超过阈值。

有没有一种方法可以确保活动的CFHTTP请求永远不会超过3个?

我认为您需要在流程中实现某种日志小部件。日志将跟踪请求频率。如果没有达到阈值,那么您只需跳过CFHTTP调用的迭代。我指的不是文件日志或数据库日志,而是在应用程序甚至请求范围中实现的东西,具体取决于您的实现。没有办法限制CFHTTP本身。它基本上是一个非常简单的Java HTTP库包装器,然后直接进入底层操作系统。

如果您限制并发请求,那么这个答案的第一部分适用。如果您希望限制每秒的请求数量,那么末尾的部分适用。这个问题问了两个问题。

如果我理解正确的话,您有许多线程(作为CF正在处理的请求或CF自己创建的线程),它们都需要调用同一个速率受限的域。您需要的是一种协调访问的中心方式,以及一种控制程序执行的好方法。

我不知道CF可能支持的任何原生限制(我很乐意被证明是错误的),所以你可能不得不实现自己的限制。做到这一点的最便宜的方法是在长寿命的范围(如application)中增加和减少allowed_conenctions变量。缺点是,你必须在所有地方进行检查,如果没有备用连接,你将不得不等待。

实际上,您拥有的是一个资源池(允许的HTTP连接),我猜您希望代码等待连接空闲。CF已经为数据库连接做了这种事情。

在您的情况下,除了使用资源的许可证之外,实际上不需要在池中保留任何东西(因为HTTP连接不是长寿命的)。Java提供了一个类,它应该提供您想要的东西,Semaphore。

我还没有尝试过,但从理论上讲,像下面这样的片段应该会起作用:

//Application.cfc:onApplicationStart()
application.http_pool = CreateObject("java","java.util.concurrent.Semaphore").init(3)
//Meanwhile, elsewhere in your code
application.http_pool.acquire()
//Make my HTTP call
application.http_pool.release()

您甚至可以包装HTTP对象以提供此功能,而不必每次都使用获取/发布,这将使其更加可靠。

编辑如果你想限制费率,可以看看番石榴的RateLimit,它与上面的Semaphore有相同的通用接口,但为你实现了费率限制。您需要将番石榴添加到ColdFusion的类路径中,或者使用JavaLoader或内置类加载功能的CF10。

最新更新