我正在创建一个应用程序,它将不断向服务器发送CFHTTP请求以搜索项目,以及发送更多CFHTTP请求以对任何返回的结果执行操作。
我遇到的问题是服务器的最大阈值为每秒3个请求,即使我每隔4毫秒尝试执行一次睡眠调用,它也无法正常工作,尽管它会延迟,但CFHTTP请求如果它需要几秒钟才能返回,那么就可以排队,然后它会在同一秒内发送多个触发超出阈值的数据。
有没有办法可以确保永远不会有超过3个活动的CFHTTP请求?
答案 0 :(得分:0)
我认为您需要在流程中实现某种日志记录小部件。日志将跟踪请求频率。如果不满足阈值,那么您将跳过CFHTTP调用的迭代。我不是指文件日志或数据库日志,而是在应用程序中实现的东西,甚至是请求范围,具体取决于您的实现。没有办法限制CFHTTP本身。它基本上是一个围绕Java HTTP库的非常简单的包装器,然后直接进入底层操作系统。
答案 1 :(得分:0)
如果您要限制并发请求,则此答案的第一部分适用。如果您希望限制每秒的请求数,那么最后的位应用。这个问题要问两件事。
如果我理解正确,你有许多线程(无论是请求CF正在处理还是线程CF已创建自己),所有线程都需要调用相同的速率限制域。您需要的是协调访问的核心方式,以及控制程序执行的好方法。
我不知道CF可能支持的任何本机限制(我很高兴被证明是错误的)所以你可能必须实现自己的。这种廉价的'n'方式是在一个长期存在的范围内增加和减少allowed_conenctions
变量,例如appliation。缺点是你必须在所有地方实施检查,如果没有备用连接,你将不得不以某种方式等待。
你真正拥有的是resource poo l(允许的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对象以提供此功能,而无需每次都使用获取/发布,这将使其更可靠。
EDIT 你想要限制费率,看看与上面的Semaphore具有相同通用接口的番石榴RateLimiter,但是为你实现速率限制。您需要将guava添加到ColdFusion的类路径中,或者使用JavaLoader或使用内置了类加载工具的CF10。