我正在制作一个应用程序,它将不断向服务器发送 CFHTTP 请求以搜索项目,并发送进一步的 CFHTTP 请求以对任何返回的结果执行操作。
我遇到的问题是服务器的最大阈值为每秒 3 个请求,即使我尝试每 4 毫秒执行一次睡眠调用,它也无法正常工作,因为虽然它会延迟,但 CFHTTP 请求可以排队如果它们需要几秒钟才能返回,那么它会尝试在同一秒内发送多个触发阈值被超过。
有没有办法可以确保活动的 CFHTTP 请求不超过 3 个?
我正在制作一个应用程序,它将不断向服务器发送 CFHTTP 请求以搜索项目,并发送进一步的 CFHTTP 请求以对任何返回的结果执行操作。
我遇到的问题是服务器的最大阈值为每秒 3 个请求,即使我尝试每 4 毫秒执行一次睡眠调用,它也无法正常工作,因为虽然它会延迟,但 CFHTTP 请求可以排队如果它们需要几秒钟才能返回,那么它会尝试在同一秒内发送多个触发阈值被超过。
有没有办法可以确保活动的 CFHTTP 请求不超过 3 个?
如果您限制并发请求,则此答案的第一部分适用。如果您希望限制每秒的请求数,那么最后的位适用。这个问题问了两件事。
如果我理解正确,您有许多线程(无论是请求 CF 正在处理还是线程 CF 自己创建)都需要调用同一个限速域。您需要的是一种协调访问的中心方式,以及一种控制程序执行的好方法。
我不知道 CF 可能支持的任何本机限制(我很高兴被证明是错误的),因此您可能必须实现自己的限制。做到这一点的廉价'n'nasty方法是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 对象以提供此功能,而不必每次都使用获取/释放,这将使其更可靠。
编辑如果您要限制速率,请查看 guava 的RateLimiter,它与上面的 Semaphore 具有相同的通用接口,但为您实现了速率限制。您需要将番石榴添加到 ColdFusion 的类路径中,或者使用 JavaLoader 或使用内置类加载工具的 CF10。
我认为您将需要在您的流程中实现某种日志小部件。日志将跟踪请求频率。如果未达到阈值,那么您将跳过 CFHTTP 调用的该迭代。我不是指文件日志或数据库日志,而是在应用程序中实现的某些内容,甚至是请求范围,具体取决于您的实现。没有办法限制 CFHTTP 本身。它基本上是一个非常简单的 Java HTTP 库包装器,然后直接进入底层操作系统。