php cURL和Rolling cURL并发方式比较 |
本文标签:php,cURL,Rolling 在实际项目或者自己编写小工具(比如新闻聚合,商品价格监控,比价)的过程中, 通常需要从第3方网站或者API接口获取数据, 在需要处理1个URL队列时, 为了提高性能, 可以采用cURL提供的curl_multi_*族函数实现简单的并发 。 复制代码 代码如下: function classic_curl($urls, $queue = curl_multi_init(); $map = array();
foreach ($urls as // $ch = curl_init();
// curl_setopt($ch,
curl_setopt($ch, curl_setopt($ch, curl_setopt($ch, curl_setopt($ch,
// curl_multi_add_handle($queue, $map[$url] }
$active = null;
// do { $mrc = curl_multi_exec($queue, } ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active > 0 && $mrc == CURLM_OK) { if (curl_multi_select($queue, do { $mrc = curl_multi_exec($queue, } ($mrc == CURLM_CALL_MULTI_PERFORM); } }
$responses = array(); foreach ($map as $responses[$url] curl_multi_remove_handle($queue, curl_close($ch); }
curl_multi_close($queue); return $responses; } 首先将所有的URL压入并发队列, 然后执行并发过程, 等待所有请求接收完之后进行数据的解析等后续处理. 在实际的处理过程中, 受网络传输的影响, 部分URL的内容会优先于其他URL返回, 但是经典cURL并发必须等待最慢的那个URL返回之后才开始处理, 等待也就意味着CPU的空闲和浪费. 如果URL队列很短, 这种空闲和浪费还处在可接受的范围, 但如果队列很长, 这种等待和浪费将变得不可接受. 2. 改进的Rolling cURL并发方式 仔细分析不难发现经典cURL并发还存在优化的空间, 优化的方式时当某个URL请求完毕之后尽可能快的去处理它, 边处理边等待其他的URL返回, 而不是等待那个最慢的接口返回之后才开始处理等工作, 从而避免CPU的空闲和浪费. 闲话不多说, 下面贴上具体的实现: 复制代码 代码如下: function rolling_curl($urls, $queue = curl_multi_init(); $map = array();
foreach ($urls as $ch = curl_init();
curl_setopt($ch, curl_setopt($ch, curl_setopt($ch, curl_setopt($ch, curl_setopt($ch,
curl_multi_add_handle($queue, $map[(string) }
$responses = array(); do { while (($code = curl_multi_exec($queue,
if ($code != CURLM_OK) { break;
// while ($done = curl_multi_info_read($queue))
// $info = curl_getinfo($done[handle]); $error = curl_error($done[handle]); $results = callback(curl_multi_getcontent($done[handle]), $responses[$map[(string)
// curl_multi_remove_handle($queue, curl_close($done[handle]); }
// if ($active > 0) { curl_multi_select($queue, }
} ($active);
curl_multi_close($queue); return $responses; } 3. 两种并发实现的性能对比 改进前后的性能对比试验在LINUX主机上进行, 测试时使用的并发队列如下: http://a.com/item.htm?id=14392877692 复制代码 代码如下: function callback($data, preg_match_all(/<h3>(.+)<\/h3>/iU, usleep($delay); return compact(data, } 数据处理回调无延迟时: Rolling Curl略优, 但性能提升效果不明显 。 ![]() |