摘要
我有一些PHP 5.4代码使用多卷曲其取出一批的Facebook / Instagram的照片并联。该代码已经工作了多年,据我可以告诉一切都没有改变。
我多卷曲请求添加到“多”的要求。每个卷曲的请求得到了CURLOPT_TIMEOUT
。我看到的问题是,突然间,我的一些要求没有完成,直到超时达到(无论我怎样设置超时)。
码
我做这样的事情(简体):
do {
while (CURLM_CALL_MULTI_PERFORM === curl_multi_exec($mh, $running));
// Wait for activity on any curl-connection (optional, reduces CPU)
curl_multi_select($mh);
// a request was just completed -- find out which one
while($done = curl_multi_info_read($mh))
{
$completedCurlRequest = $done['handle'];
//save the file
do_some_work(completedCurlRequest);
curl_multi_remove_handle($mh, $completedCurlRequest);
}
} while ($running);
我用这个脚本来运行约40并行请求分批取一些图片(来自Facebook)。他们中的大多数需要500ms左右才能完成。但是,有少数请求的“挂”(直到CURLOPT_TIMEOUT
)才到达。
基本上,curl_multi_select
步骤拍摄整个超时。或者,如果我删除curl_multi_select
线,外环旋转(烧CPU),直到超时。
注意事项
问题
更新这里是什么,我回去从一个缓慢的请求时,它终于完成:
信息
"content_type": "image/jpeg",
"http_code": 200,
"header_size": 377,
"request_size": 180,
"total_time": 15.001012, //<----- Total time == CURLOPT_TIMEOUT
"namelookup_time": 0.007149,
"connect_time": 0.12018,
"pretransfer_time": 0.441911,
"size_download": 40714,
"speed_download": 2714,
"download_content_length": -1, //<------Not set
HEADER
HTTP/2 200
content-type: image/jpeg
x-haystack-needlechecksum: 3529661797
timing-allow-origin: *
access-control-allow-origin: *
cache-control: max-age=1209600, no-transform
date: Mon, 04 Feb 2019 14:04:17 GMT
access-control-expose-headers: X-FB-CEC-Video-Limit
它缺少content-length
头,但似乎总是这样的情况在第一时间文件被取出。仅1或50个并行请求2是缓慢的,但所有的请求的丢失其内容长度报头。
如果我再次读取相同的文件,它是非常快的,我的确看到内容长度设定这个时候
信息
"download_content_length": 52721,
HEADER
content-length: 52721
我目前的理论是,有Facebook的文件服务器,这意味着连接,即使已发送数据有时不被关闭的错误,所以连接保持打开状态,直到超时。在不存在(可选的)Content-Length头通过Facebook的文件服务器被发送的,卷曲可以不知道,如果有效载荷是完整的,并且如此挂起。
我目前的解决办法是“黄金”的文件服务器首先庄家对图像的请求没有身体,就像这样:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_NOBODY, 1);
curl_exec($ch);
这是一个非常快速的过程,因为没有返回图像。我真正做到这一点,使用异步多卷曲的背景下,这样我就可以做一些其他的处理得到。
吸文件服务器后,对文件的后续请求比以前更快,因为内容长度是已知的。
这是一个有点笨拙的办法,但在没有从Facebook的任何响应,到目前为止我不知道还能做什么。