我正在使用'滚动'cURL多实现(就像这篇SO帖子,基于这个cURL代码).它可以同时使用多达100个请求来处理数千个URL,其中5个脚本实例作为守护进程运行(是的,我知道,这应该用C语言编写).
这是问题:处理完~200,000 url(在5个实例中)curl_multi_exec()似乎打破了脚本的所有实例.我已经尝试关闭脚本,然后重新启动,同样的事情发生(不是在200,000网址后,但在重新启动时),脚本挂起调用curl_multi_exec().
我把脚本放到'单一'模式,处理一个常规的cURL句柄,并且工作正常(但它不是我需要的速度).我的日志记录让我怀疑它可能遇到了缓慢/有问题的连接(因为它似乎经常在URL上处理然后再次挂起),但这意味着我CURLOPT_TIMEOUT的个别句柄被忽略了.或者也许只是通过cURL运行那么多请求的东西.
有人听说过这样的事吗?
示例代码(再次基于此):
//some logging shows it hangs right here, only looping a time or two
//so the hang seems to be in the curl call
while(($execrun =
curl_multi_exec($master, $running)) == CURLM_CALL_MULTI_PERFORM);
//code to check for error or process whatever returned
Run Code Online (Sandbox Code Playgroud)
我已CURLOPT_TIMEOUT设置120,但在curl_multi_exec()最终返回一些数据的情况下,它是在等待10分钟后.
我有一堆测试/检查还没有做,但想到也许这可能会敲响一个人.
经过大量测试后,我相信我已经找到了造成这个特殊问题的原因.我不是说其他答案是不正确的,只是在这种情况下不是我遇到的问题.
据我所知,curl_multi_exec()直到所有DNS(失败或成功)得到解决后才会返回.如果有一堆带坏域的网址curl_multi_exec()至少没有返回:
(time it takes to get resolve error) * (number of urls with bad domain)
Run Code Online (Sandbox Code Playgroud)
这是其他人发现了这个:
只是关于cURL多功能的异步性质的说明:DNS查找不是(据我所知)今天的异步.因此,如果您的组的一次DNS查找失败,那么之后的URL列表中的所有内容也都会失败.我们实际上每天更新我们的服务器上的hosts.conf(我认为?)文件,以便解决这个问题.它获取IP地址而不是查找它们.我相信它正在进行中,但不确定它是否已经改变了cURL.
此外,测试显示cURL(至少我的版本)确实遵循CURLOPT_CONNECTTIMEOUT设置.当然,多周期的第一步可能仍需要很长时间,因为cURL等待每个URL解析或超时.
我认为你的问题归结为:
(62)CURLOPT_TIMEOUT无法与常规multi和multi_socket接口一起正常工作.应用程序的解决方法是在时间结束后简单地删除简易句柄.
如果是这种情况,您应该观察您的卷曲手柄超时并将其从多池中删除.